IntentService介绍
1.IntentService 是什么
- 一个封装了HandlerThread和Handler的异步框架。
- 是一种特殊Service,继承自Service,是抽象类,必须创建子类才可以使用。
- 可用于执行后台耗时的任务,任务执行后会自动停止
- 具有高优先级(服务的原因),优先级比单纯的线程高很多,适合高优先级的后台任务,且不容易被系统杀死。
- 启动方式和Service一样。
- 可以多次启动,每个耗时操作都会以工作队列的方式在IntentService的onHandleIntent回调方法中执行。
- 串行执行。
2. IntentService的执行方式是串行还是并行
串行
3. IntentService可以执行大量的耗时操作?
- 如果只有一个任务,是可以进行耗时操作的。
- 如果有很多任务,由于内部的HandlerThread是串行执行任务,会导致耗时操作阻塞了后续任务的执行。
4. IntentService和Service的区别
- 继承自Service
- IntentService任务执行完后会自动停止
- IntentService和Service优先级一致,比Thread高。
- 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底层原理
- 构造了HandlerThread
- 并在每部保存了HandlerThread的Looper
- 并且使用该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
- HandlerThread会串行的取出任务并且执行,会调用ServiceHandler的handleMessage去处理任务。
- handlerMessage会去调用我们自定义的onHandleIntent
- 任务执行完毕后通过stopSelf(startId)停止Service。
- 任务结束后,在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()
- 采用stopSelf()——会立即停止服务
- 采用stopSelf(startId),会等所有消息全部处理完毕后,才会停止。
会判断启动服务次数是否与startId相等
4. IntentService是如何停止HandlerThread的Looper消息循环的?
- 调用stopSelf(startId)后。
- 任务全部执行完,会停止服务,并且回调onDestory()。调用Looper的quit()方法即可
5. IntentService 多次startService会多次回调onHandleIntent()的内部流程?
- startService()->onStartCommand()->onStart()
- 通过HandlerThread的handler去发送消息。
- 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的源码总结:
- IntentService通过发送消息的方式向HandlerThread请求执行任务
- HandlerThread中的looper是顺序处理消息,因此有多个后台任务时,都会按照外界发起的顺序排队执行
- 启动流程:onCreate()->onStartCommand()->onStart()
- 消息处理流程:ServiceHandler.handleMessage()->onHandleIntent()
参考:
IntentService详解