IntentService介绍

1.IntentService 是什么

  1. 一个封装了HandlerThread和Handler的异步框架。
  2. 是一种特殊Service,继承自Service,是抽象类,必须创建子类才可以使用。
  3. 可用于执行后台耗时的任务,任务执行后会自动停止
  4. 具有高优先级(服务的原因),优先级比单纯的线程高很多,适合高优先级的后台任务,且不容易被系统杀死。
  5. 启动方式和Service一样。
  6. 可以多次启动,每个耗时操作都会以工作队列的方式在IntentService的onHandleIntent回调方法中执行。
  7. 串行执行。

 

2. IntentService的执行方式是串行还是并行

  串行

3. IntentService可以执行大量的耗时操作?

  1. 如果只有一个任务,是可以进行耗时操作的。
  2. 如果有很多任务,由于内部的HandlerThread是串行执行任务,会导致耗时操作阻塞了后续任务的执行。

4. IntentService和Service的区别

  1. 继承自Service
  2. IntentService任务执行完后会自动停止
  3. IntentService和Service优先级一致,比Thread高。
  4. Service处于主线程不能直接进行耗时操作; IntentService内部有HandlerThread,可以进行耗时操作。

 

5. IntentService的基本使用

1. 定义IntentService,实现onHandleIntent()'

public class LocalIntentService extends IntentService {
    public static final String TAG="LocalIntentService";
    public LocalIntentService( ) {
        super(TAG);
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        String task=intent.getStringExtra("task");
        Log.e(TAG, "onHandleIntent: task:"+task );
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.e(TAG, "onCreate: " );
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.e(TAG, "onDestroy: " );
    }
}

  2.AndroidMainfest.xml 中声明ItnentService

<service android:name=".LocalIntentService"/>

  3. 开启IntentService

 findViewById(R.id.bt1).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent service=new Intent(MainActivity.this,LocalIntentService.class);
                service.putExtra("task","task1");
                startService(service);

                service.putExtra("task","task2");
                startService(service);

                service.putExtra("task","task3");
                startService(service);

                service.putExtra("task","task4");
                startService(service);

            }
        });

  

日志:

 

6. 源码和原理机制

 1.IntetntService的OnCreate底层原理

  1. 构造了HandlerThread
  2. 并在每部保存了HandlerThread的Looper
  3. 并且使用该Looper创建了ServiceHandler
        //IntentService第一次启动调用
        public void onCreate() {
            super.onCreate();
            //1. 创建一个HanlderThread
            HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
            thread.start();
            //2. 通过HanlderThread的Looper来构建Handler对象mServiceHandler
            mServiceLooper = thread.getLooper();
            mServiceHandler = new ServiceHandler(mServiceLooper);
        

2. IntentService的ServiceHandler

  1. HandlerThread会串行的取出任务并且执行,会调用ServiceHandler的handleMessage去处理任务。
  2. handlerMessage会去调用我们自定义的onHandleIntent
  3. 任务执行完毕后通过stopSelf(startId)停止Service。
  4. 任务结束后,在onDestory()中会退出HandlerThread中Looper的循环。

  

        //ServiceHandler接收并处理onStart()方法中发送的Msg
        private final class ServiceHandler extends Handler {
            public ServiceHandler(Looper looper) {
                super(looper);
            }
            @Override
            public void handleMessage(Message msg) {
                //1. 直接在onHandleIntent中处理(由子类实现)
                onHandleIntent((Intent)msg.obj);
                /**=================================================
                 * 2. 尝试停止服务(会等待所有消息都处理完毕后,才会停止)
                 *   不能采用stopSelf()——会立即停止服务
                 *================================================*/
                stopSelf(msg.arg1); //会判断启动服务次数是否与startId相等
            }
        }

        public void onDestroy() {
            mServiceLooper.quit();
        }//销毁时会停止looper

  

 

3. IntentService内部去停止Service为什么不直接采用stopSelf()

  1. 采用stopSelf()——会立即停止服务
  2. 采用stopSelf(startId),会等所有消息全部处理完毕后,才会停止。会判断启动服务次数是否与startId相等

4. IntentService是如何停止HandlerThread的Looper消息循环的?

  1. 调用stopSelf(startId)后。
  2. 任务全部执行完,会停止服务,并且回调onDestory()。调用Looper的quit()方法即可

5. IntentService 多次startService会多次回调onHandleIntent()的内部流程?

  1. startService()->onStartCommand()->onStart()
  2. 通过HandlerThread的handler去发送消息。
  3. HandlerThread在处理任务时,会去调用onHandleIntent方法。

 

public abstract class IntentService extends Service {
        private volatile Looper mServiceLooper;
        private volatile ServiceHandler mServiceHandler;
        ...省略...

        //IntentService每次启动都会调用
        public int onStartCommand(Intent intent, int flags, int startId) {
            //3. 直接调用onStart
            onStart(intent, startId);
            return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
        }
        public void onStart(Intent intent, int startId) {
            //4. 通过mServiceHandler发送一个消息(该消息会在HanlderThread中处理)
            Message msg = mServiceHandler.obtainMessage();
            msg.arg1 = startId;
            msg.obj = intent;
            mServiceHandler.sendMessage(msg);
        }
        //2. 该Intent与startService(intent)中的Intent完全一致
        protected abstract void onHandleIntent(Intent intent);

}

  

6. IntentService的源码总结:

  1. IntentService通过发送消息的方式向HandlerThread请求执行任务
  2. HandlerThread中的looper是顺序处理消息,因此有多个后台任务时,都会按照外界发起的顺序排队执行
  3. 启动流程:onCreate()->onStartCommand()->onStart()
  4. 消息处理流程:ServiceHandler.handleMessage()->onHandleIntent()

 

 

参考:

IntentService详解

 

posted @ 2019-04-25 19:47  段合江  阅读(504)  评论(0编辑  收藏  举报