概述:
IntentService是Service的子类,起Service的时候如果需要处理耗时任务往往需要启动一个Thread,因为Service是运行在主线程里的。IntentService内部有一个HandlerThread,在IntentService的Oncreate方法中就启动了这个HandlerThread。所以IntentService就是一个有子线程有消息循环有handler的Service,并且IntentService在处理完所有任务之后会自己结束自己(调用stopSelf)。
IntentService缺点,无法等待,Service处理完事情就自动关闭,不适合处理长期任务,比如监听socket,此种场景用Service更合适。
有个场景特别适用,当activity要退出的时候,我们又想保存某些数据,而保存数据比较耗时,此时可以用IntentService来做。也可以在activity启动一个子线程,由子线程来做,但是子线程不是四大组件,容易被杀死
问题1:IntentService跟Handler怎么关联上的?
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
onHandleIntent((Intent)msg.obj);
stopSelf(msg.arg1);
}
}
每调用一次startService会调用IntentService的onStartCommand()方法,内部调用onStart()方法
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发出去,交给Handler处理,内部的Looper负责从消息队列中取消息,然后交给ServiceHandler处理.
这时我们发现一件事情,每个消息,Handler处理完了都会调用一次stopSelf(msg.arg1);
哎,这不是直接结束Intentservice了吗?难道处理完一次消息就会关掉Service吗?
当然不是的,请看问题2
问题2:IntentService是如何结束自己的?他怎么保证所有任务都结束了?
我们来看onStart
public void onStart(Intent intent, int startId)
Service可以被start任意次。所以需要一个startId来标识当前Service被启动了多少次,比如调了2次startService,每一次startService都会调onStart,那么第一次onStart的startId就是1,第二次onStart的startId就是2.
再看stopSelf(int startId),如果当前Service的startId和stopSelf里的一致,那就停止Service,否则不做任何事情。
来看一个场景,一个Service在处理完某件事情之后,想关闭Service,可是Service可能在处理别的事情。
stopSelf()和stopSelf(int startId)区别
public final void stopSelf() {
stopSelf(-1);
}
startSelf(int startId)会检查startId与当前Service的startId是否一致,一致就stop,不一致就不做任何事
代码com.android.server.am.ActiveServices#stopServiceTokenLocked
<span style="font-size:14px;"> if (r.getLastStartId() != startId) {
return false;
}</span>
stopSelf()就不检查,会直接stop。