IntentService
简介
IntentService继承Service,Service运行在主线程,决定了Service不能执行耗时任务,因此使用IntentService。
使用IntentService比较简单,只需要继承IntentService并重写onHandleIntent(@Nullable Intent intent)方法即可。
IntentService封装了Looper和Handler
初始化Looper和Handler
@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,HandlerThread封装和实例化了Looper并和当前Thread绑定,HandlerThread.start()则启动了消息循环,此消息循环一直阻塞于读取消息
- 实例化mServiceLooper这个Looper对象
- 实例化mServiceHandler这个Handler对象
到此,后台工作线程已经启动,Looper对象和Handler对象已经创建完毕。
IntentService onStart
@Override
public void onStart(@Nullable Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
onCreate和onStart是自动调用,在onStart()函数中自动发送一条消息,并且把启动Service的Intent参数对象放到Message对象中,sendMessage()后此消息进入消息队列,随后被阻塞的读取消息处取得了发送的消息对象,进入Handler中的handleMessage(Message msg)函数
@Override
public void handleMessage(Message msg) {
onHandleIntent((Intent)msg.obj);
stopSelf(msg.arg1);
}
在onStart()函数中发送了一个Message,通过消息循环,程序自动进入到handleMessage()函数,自动进入onHandleIntent((Intent)msg.obj)函数中,而onHandleIntent((Intent)msg.obj)函数是一个抽象函数,需要由IntentService的实现类来实现,因此最终实现了继承IntentService并重写onHandleIntent((Intent)msg.obj)函数实现了在子线程中处理Service耗时任务的功能。
IntentService何时退出
在onHandleIntent函数执行完成后,执行stopSelf(int startId)函数,此函数会调用Server的stopSelf(int startId)函数,退出Service,随后IntentService的onDestroy()函数会执行,进而调用mServiceLooper.quit()函数退出消息循环,当执行quit()函数后,调用mQueue.quit(false)函数,此时Looper从消息队列中取得的消息对象为null,则HandlerThread的run()方法也会执行完成,线程退出,Service最终执行完成所有业务,也会退出,到此整个IntentService的执行过程结束。
IntentService退出时为什么调用quit()函数而不调用quitSafely()函数
- quit()函数执行后,消息队列中即使有没有处理的消息,依然会直接退出消息循环,因为在执行quit(false)函数时,会先把消息队列中的消息全部清除掉
- quitSafely()函数需要待消息队列中的消息处理完毕后才退出消息循环
- 在IntentService中,Handler只会发送一条Message,而此Message,一定会被handle,因此此时消息队列中是没有其他消息的,因此也就没有必要执行quitSafely()函数