IntentService

2020-07-06  本文已影响0人  Doctor_Xu

简介

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);
    }
  1. onCreate函数中实例化HandlerThread,HandlerThread封装和实例化了Looper并和当前Thread绑定,HandlerThread.start()则启动了消息循环,此消息循环一直阻塞于读取消息
  2. 实例化mServiceLooper这个Looper对象
  3. 实例化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()函数

  1. quit()函数执行后,消息队列中即使有没有处理的消息,依然会直接退出消息循环,因为在执行quit(false)函数时,会先把消息队列中的消息全部清除掉
  2. quitSafely()函数需要待消息队列中的消息处理完毕后才退出消息循环
  3. 在IntentService中,Handler只会发送一条Message,而此Message,一定会被handle,因此此时消息队列中是没有其他消息的,因此也就没有必要执行quitSafely()函数
上一篇 下一篇

猜你喜欢

热点阅读