主要参考自:《Android 开发艺术探索》
IntentService 是一种特殊的Service,它继承了 Service 并且它是一个抽象类,因此必须创建它的子类才能使用 IntentService。
其内部维护了一个 Looper 和一个 Handler。
private volatile Looper mServiceLooper;
private volatile ServiceHandler mServiceHandler;
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);
}
}
其中 Handler 为 ServiceHandler 类型,是其一个内部类。
在它 onCreate() 中会初始化其成员变量。
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);
}
并且,其内部是基于 HandlerThread 的,会开启 HandlerThread 类型的子线程,从而开启对应的 Looper,以及实例化 ServiceHandler。
每次启动 IntentService,它的 onStartCommand()
方法就会被调用一次。
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
public void onStart(@Nullable Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
onStartCommand()
又会进一步调用 onStart()
,同时把通过 Context#startService(intent)
传递过来的 Intent 传递到 onStart()
方法中。
而在 onStart() 中会通过 mServiceHandler 将传递过来的 intent 进一步传递到子线程去处理,即 ServiceHandler#handleMessage()
中处理。
public void handleMessage(Message msg) {
onHandleIntent((Intent)msg.obj);
stopSelf(msg.arg1);
}
在 handleMessage() 中,会调用 IntentService#onHandleIntent()
,该方法就是需要我们自己实现的。之后,还会调用 Service#stopSelf(int startId)
来尝试停止服务(该方法会等待所有消息都处理完毕才终止服务,而 Service#stopSelf()
则会立即停止服务),因此不需要自己去调用 stopSelf()
方法来停止
对于 Service#stopSelf(int startId)
,在停止服务之前会判断最近启动服务的次数是否和 startId 相等,如果相等则立刻停止服务,不相等则不停止。
因为 Handler 中的 Looper 是顺序处理消息的,这意味着 IntentService 也是顺序执行任务的,当多个任务同时存在时,这些任务会依次按照发起并放入消息队列的顺序依次执行。
另外,IntentService 提供了一个 onBind()
方法的默认实现,它返回 null。