- IntentService是android为我们提供的一个Async的Service,其父类是Service,运行在一个单独的线程。可以顺序执行多个任务,执行完任务之后自动的调用stopSelf方法来停止服务
IntentService的优点 :异步, 顺序执行多个任务(通过Looper的MessageQueque管理) 执行任务完成之后自动停止 ,而普通的Service 运行在ui线程 如果开启多个线程下载的话,无法控制顺序 而且运行完成之后 不会自动停止 得用户手动判断 容易泄漏内存
现在我们从源码的角度分析一下IntentService的工作流程
public void onCreate() { super.onCreate(); HandlerThread thread = new HandlerThread("IntentService[" + mName + "]"); thread.start(); mServiceLooper = thread.getLooper(); mServiceHandler = new ServiceHandler(mServiceLooper); }
其在onCreate中完成了上面功能呢个,创建了一个HandlerThread,之后启动了Handler,又在HanlderThread中拿到了子线程的Looper,并通过子线程的Looper创建了一个ServiceHanlder
- 我们先来看一下ServiceHanlder是什么?
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
// 运行在子线程 因为拿的的是HandlerThread的looper
onHandleIntent((Intent)msg.obj);
stopSelf(msg.arg1);
// 不是说调用stopSelfservice就会停止 判断执行次数和startId是否一致 一致的话 就停止
}
}
- 发现ServiceHanlder其实就是一个Handler,这里在Hanlder中的HanldeMessage方法中调用了OnHandleIntent方法(也就是子类实现的方法)
- 我们可以看到ServiceHandler中的Looper是HandlerThread的Looper,也就是子线程的Looper,我们的Handler的handleMessage方法运行在哪一个线程,不是Hanlder在哪一个线程中创建的handleMessage就运行在哪一个线程,而是有Looper所在的线程决定,handleMessage运行在哪一个线程
- 接下来我们看一下HandleThread源码
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
- 其核心代码是run方法,也就 是在run中给ThreadLocal存储了一个Looper,那么我们的ServiceHanlder也就可以直接拿到HandleThread的Looper,也就是直接运行在HandlerThread所在的线程
- 我们知道,当我们startService的时候,service的生命周期是这样的
- onCreate–>onStart onStart可以执行多次,我们的onStart源码是什么呢?
@Override
public void onStart(Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
- 我们发现 onStart其实是将Intent和startId封装成了一个Message,之后交给了ServiceHandler处理,而我们的ServiceHanlder中的Looper是子线程HanlderThread的Looper,因此ServiceHanlder的handleMessage方法运行在子线程,因此可以在这里进行Async操作
而handleMessage方法干什么呢?
public void handleMessage(Message msg) {
onHandleIntent((Intent)msg.obj); stopSelf(msg.arg1); }
原来在handleMessage方法中回调了子类的onHandleIntent方法,那么我们的onHandleIntent也就运行在子线程中
- 之后就是stopSelf() 这里不是说调用了stopSelf service就结束,而是判断了startid是否和启动次数相等,如果相等的话 才结束
- stopSelf源码
public final void stopSelf(int startId) {
if (mActivityManager == null) {
return;
}
try {
mActivityManager.stopServiceToken(
new ComponentName(this, mClassName), mToken, startId);
} catch (RemoteException ex) {
}
}
- 我们每启动同一个service,startId就加1,如果启动10次的话,那么startId为10,而对应每一个Intent传递过来的是从1–10,只有最后一个intent任务执行完了之后,才会结束服务
- 这里之所以说IntentService是按照队列执行的原因是:在onStart中,ServiceHandler调用的是handleMessage()方法,没有发送延迟或者插入队列
- 下面是一张原理图