近期在做启动优化的时候用到了IntentService,就是把初始化的一些功能搬到IntentService里去延迟处理,加快了启动的时间,因此记录下IntentService内部的实现原理
一、IntentService有哪些特点
二、如何使用
public class Demo extends IntentService { public Demo() { //给工作线程命名 super("demoService"); } //重写onHandleIntent方法 @Override protected void onHandleIntent(@Nullable Intent intent) { } }
三、生命周期分析
多次启动IntentService并不会多次执行onCreate方法,onCreate只会执行一次,当有多个任务的时候启动多次IntentService会多次执行onStartCommand方法,当所有任务执行完毕会调用onDestroy方法。
四、IntentService内部原理
1.service启动时的处理
//IntentService @Override public void onCreate() { super.onCreate(); //启动HandlerThread线程 HandlerThread thread = new HandlerThread("IntentService[" + mName + "]"); thread.start(); //取到HandlerThread线程里的looper mServiceLooper = thread.getLooper(); //创建handler,该handler的looper对象是子线程的 mServiceHandler = new ServiceHandler(mServiceLooper); }
//HandlerThread对象 public class HandlerThread extends Thread { Looper mLooper; //忽略其他方法 @Override public void run() { //可以看到这是一个子线程,在run方法里创建了looper,也同时创建了MessageQueue mTid = Process.myTid(); Looper.prepare(); synchronized (this) { mLooper = Looper.myLooper(); notifyAll(); } Process.setThreadPriority(mPriority); onLooperPrepared(); //开启了loop循环 因此这个run方法会一直执行(除非looper停止) Looper.loop(); mTid = -1; } //忽略其他方法 }
2.service收到执行任务的处理
public abstract class IntentService extends Service { private final class ServiceHandler extends Handler { public ServiceHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { //handler的dispatchMessage之后就会调用该方法 //该方法会执行onHandleIntent,因此我们在使用IntentService的时候要重写onHandleIntent onHandleIntent((Intent)msg.obj); //msg.arg1是startId,这里为啥要传startId呢? //每次执行完startId都会去调用stopSelf,该方法会判断当前service是否还有 //其他的任务没有执行,如果有就不会停止服务,如果没有其他任务了那么就停止服务 stopSelf(msg.arg1); } } @Override public void onStart(@Nullable Intent intent, int startId) { //每次新来的执行任务都会通过handler来处理,先放到消息队列里依次去执行 //每次的startId都不一样且都是大于0的,可以根据startId来为后期stopSelf时作为依据 Message msg = mServiceHandler.obtainMessage(); msg.arg1 = startId; msg.obj = intent; mServiceHandler.sendMessage(msg); } //多次启动service会执行多次onStartCommand方法 @Override public int onStartCommand(@Nullable Intent intent, int flags, int startId) { //调用了onStart方法 onStart(intent, startId); return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY; } @WorkerThread protected abstract void onHandleIntent(@Nullable Intent intent); }
3.service停止
@Override public void onDestroy() { //service执行onDestroy的时候调用HandlerThread里的looper.quit方法 //这样HandlerThread的run方法就会执行完毕不会处于阻塞状态 mServiceLooper.quit(); }
五、总结
IntentService继承了Service,内部采用了handler+thread的方式来将需要执行的任务存放到MessageQueue,在thread里的run方法里不断的轮询消息,并通过onHandleIntent方法来通知调用者去处理,在每次执行完onHandleIntent后都会去判断一下当前是否还有等待执行的任务,如果没有的话那么就自动停止服务。