IntentService 是Android为我们提供的一个类,继承Service类,
第一步,先来看看源码里面开头的注释:
-
/**
-
* IntentService is a base class for {@link Service}s that handle asynchronous
-
* requests (expressed as {@link Intent}s) on demand. Clients send requests
-
* through {@link android.content.Context#startService(Intent)} calls; the
-
* service is started as needed, handles each Intent in turn using a worker
-
* thread, and stops itself when it runs out of work.
-
*
-
* <p>This "work queue processor" pattern is commonly used to offload tasks
-
* from an application's main thread. The IntentService class exists to
-
* simplify this pattern and take care of the mechanics. To use it, extend
-
* IntentService and implement {@link #onHandleIntent(Intent)}. IntentService
-
* will receive the Intents, launch a worker thread, and stop the service as
-
* appropriate.
-
*
-
* <p>All requests are handled on a single worker thread -- they may take as
-
* long as necessary (and will not block the application's main loop), but
-
* only one request will be processed at a time.
-
*/
由上至少可以知道两点:
1. IntentService 基于 类Service,用来处理异步请求。客户端可以通过startService(Intent)来发出请求,该Service会在需要的时候创建,通过使用一个工作线程来处理请求,当所有的请求都处理完以后自动关闭;
2. 所有请求都单独由一个工作线程进行处理。
第二步,我们看看IntentService的成员变量:
-
private volatile Looper mServiceLooper;
-
private volatile ServiceHandler mServiceHandler;
-
private String mName;
-
private boolean mRedelivery;
ServiceHandler是一个静态内部类,代码如下:
-
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);
-
}
-
}
在handleMessage(Message msg)方法里,会调用onHandleIntent(Intent intent)方法处理请求,这一步说明了我们在使用IntentService时为什么得重载onHandleIntent(Intent intent)方法并在其中实现我们自己的处理;
接着,在处理完请求后就会调用stopSelf(int startId)尝试停止自己,注意这里调用的是stopSelf(int startId),而不是sotpSelf(),实际上stopSelf也是调用stopSelf(int startId),只不过startId指定为-1,两者的区别在于stopSelf(int startId)会等所有请求处理完才停止,而stopSelf()是直接停止。
其中startId的解释如下:
// startId A unique integer representing this specific request to start
可以简单理解startId记录了该Service被启动的次数,从1开始计算,每启动一次自增1,从ServiceRecord中可以看出,如下:
-
final class ServiceRecord extends Binder {
-
...
-
private int lastStartId; // identifier of most recent start request.
-
...
-
public int getLastStartId() {
-
return lastStartId;
-
}
-
public int makeNextStartId() {
-
lastStartId++;
-
if (lastStartId < 1) {
-
lastStartId = 1;
-
}
-
return lastStartId;
-
}
-
...
-
}
由于这其中涉及Serivce创建和启动的复杂过程,这里只是提一下,故本节不深入讨论
第三步,我们来看看几个回调方法,我们知道Service创建时回调方法的调用顺序为:onCreate -> onStartCommand -> onStart,因此我们先看onCreate(),实现如下:
-
@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);
-
}
主要步骤如下:
1. 创建线程HandlerThread并启动
2. 获取线程的Looper,赋值给mServiceLooper
3. 以该Looper对象做参数创建ServiceHandler
关于HandlerThread的分析可以参考:HandlerThread浅析
接着看onStartCommand()
-
/**
-
* 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;
-
}
这里说明了不应该重载该方法,可以看到在该方法实现只是简单地调用了onStart(),把startService(Intent intent)传递过来的intent以及对应的startId传递给了onStart(), onStart()方法的实现如下:
-
@Override
-
public void onStart(Intent intent, int startId) {
-
Message msg = mServiceHandler.obtainMessage();
-
msg.arg1 = startId;
-
msg.obj = intent;
-
mServiceHandler.sendMessage(msg);
-
}
在onStart()方法里,获取和Servicehandler关联的Message对象msg,并把intent赋值给msg的obj,把startId赋值给msg.arg1,然后发送msg,该Message会被MessageQueue接收,然后mServiceLooper会从该队列中取出,交给ServiceHandler处理,这样在就会执行前面介绍ServiceHandler的handleMessage(Message msg)方法。