您的位置:首页 > 移动开发 > Android开发

Android IntentService

2015-12-12 16:05 387 查看
/**

 *

 * 转载请标明出处:http://blog.csdn.net/u013598111/article/details/50274211

 *   @author:【JunTao_sun】
 *

 *

*/

IntentService是Service的子类,是一个通过Context.startService(Intent)启动,

以处理异步请求的Service,使用时你只需要继承IntentService和重写其中的

onHandleIntent(Intent)方法接收一个Intent对象,在适当的时候会停止自己(一般在工作完成的时候).

所有的请求的处理都在一个工作线程中完成,它们会交替执行(但不会阻塞主线程的执行),

一次只能执行一个请求.

 

  private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}

@Override
public void handleMessage(Message msg) {
onHandleIntent((Intent)msg.obj);
stopSelf(msg.arg1);
}
}ServiceHandler是IntentService的内部类 是handler的子类 

当有消息被加入消息队列  handlemessage会调用OnHandleIntent函数 处理intent

stopself(int startID) 不同于stopself()会直接停止服务   带参数的它会匹配startID是否一致 再停止服务。

如果同时有多个服务启动请求发送到onStartCommand(),不应该在处理完一个请求后调用stopSelf();

因为在调用此函数销毁service之前,可能service又接收到新的启动请求,如果此时service被销毁,

新的请求将得不到处理。此情况应该调用stopSelf(int startId)。

@Override
public void onCreate() {
// TODO: It would be nice to have an option to hold a partial wakelock
// during processing, and to have a static startService(Context, Intent)
// method that would launch the service & hand off a wakelock.

super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();

mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
在Oncreate方法中 初始化线程HandlerThread 并开始启动 。

初始化ServiceHandler。得到HandlerThread  里的消息轮询器 。

把mServiceLooper消息轮询器
做参数构造一个hanler对象 也就是初始化ServiceHandler。

下边是HandlerThread 和looper的源码 

@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}looper的:

public static void prepare() {
prepare(true);
}

private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper(quitAllowed));
} HandlerThread   的run方法 里调用 Looper.prepare(); 由源码可知 sThreadlocal 是成员变量 ThreadLocal类 相当于map变量副本,

如果sThreadlocal 已经有looper了 抛异常 ->一个线程只能有一个looper ,没有则存储在sThreadlocal 。

接着 HandlerThread 里调用looper的静态方法 获得looper.,

public static Looper myLooper() {
return sThreadLocal.get();
}
 public Looper getLooper() {
        if (!isAlive()) {
            return null;
        }
        
        // If the thread has been started, wait until the looper has been created.
        synchronized (this) {
            while (isAlive() && mLooper == null) {
                try {
                    wait();
                } catch (InterruptedException e) {
                }
            }
        }
        return mLooper;
    }
HandlerThread 里有个while 循环 当前线程是活的并mlooper是Null 阻塞 ,等待到mlooper不等于Null返回。

public Handler(Looper looper, Callback callback, boolean async) {
mLooper = looper;
mQueue = looper.mQueue;
mCallback = callback;
mAsynchronous = async;
} new ServiceHandler(mServiceLooper) 会调用hanler的三个构造方法

关联一个消息轮询器  此时处理消息的就是HanlerhThread的消息轮询器里的message.

继续回到IntentService的源码

/**
* You should not override this method for your IntentService. Instead,
* override {@link #onHandleIntent}, which the system calls when the IntentService
* receives a start request.
* @see android.app.Service#onStartCommand
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
每次调用startService(Intent)的时候,都会调用该Service对象的onStartCommand(Intent,int,int)方法,然后在o
4000
nStartCommand方法中做一些处理。然后我们注意到这个函数有一个int的返回值是四个常量分别是:

START_STICKY:如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null。

START_NOT_STICKY:“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务。START_REDELIVER_INTENT:重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。

START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保证服务被kill后一定能重启。

public void setIntentRedelivery(boolean enabled) {
mRedelivery = enabled;
}设置是否重新发送意图,当服务被异常Kill掉的时候  

onStartCommand  方法中 调用了onStart函数:

@Override
public void onStart(Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
 

onStart()方法 把消息发送到 ServiceHandler 处理意图 和是否停止服务

不能重写onStartCommand方法 

如果想要对意图进行处理可以 重写onHandleIntent(Intent intent)方法
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: