IntentService源码解析
作者:互联网
近期在做启动优化的时候用到了IntentService,就是把初始化的一些功能搬到IntentService里去延迟处理,加快了启动的时间,因此记录下IntentService内部的实现原理
一、IntentService有哪些特点
- 业务逻辑在子线程执行
- 多个任务不能并行执行,依次执行
- 所有的任务都执行完自定停止服务,不需要手动处理
二、如何使用
- 继承IntentService,实现onHandleIntent方法,同时也要实现构造函数
- 在清单文件注册
- startService 通过intent传入不同的标识,在onHandleIntent中获取不同标识并执行不行的任务
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后都会去判断一下当前是否还有等待执行的任务,如果没有的话那么就自动停止服务。
标签:onHandleIntent,执行,IntentService,源码,msg,解析,startId,public 来源: https://blog.csdn.net/qq_36356379/article/details/115673907