前置知识HandlerThread http://blog.csdn.net/lizhengwei1989/article/details/68065224
先大概说一下IntentService的工作流程:
当startService后会调用onStart方法,onStart方法中用handler发送消息,handler的handleMessage方法中会调用我们复写的onHandleIntent方法,任务完成后调用stopSelf(int startId)尝试停止服务。
我们先把IntentService的源码贴出来,解析直接写到源码中,方便结合代码分析:
public abstract class IntentService extends Service {
// IntentService是借助HandlerThread实现的,HandlerThread的分析单独再写一篇博客分析,这里不再分析,参考我的其他文章即可
// 这个Looper是结合HandlerThread使用的
private volatile Looper mServiceLooper;
// // 这个ServiceHandler也是结合HandlerThread使用的,具体的实现在下面
private volatile ServiceHandler mServiceHandler;
// Service的名字
private String mName;
// Service意外死亡后,重新恢复后是否继续处理以前的请求
private boolean mRedelivery;
// 内部使用的Handler
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
// 调用抽象方法onHandleIntent,onHandleIntent是我们自己继承IntentService实现的方法
onHandleIntent((Intent)msg.obj);
// stopSelf(int startId)方法的特点是传入的id和最近一次startService的启动id相同才会停止service,msg.arg1是在start方法中将startId赋值给arg1的
stopSelf(msg.arg1);
}
}
public IntentService(String name) {
super();
mName = name;
}
// 设置service意外停止后,恢复时是否继续处理上次没处理的内容,false不处理,true只会处理最近的一个请求
public void setIntentRedelivery(boolean enabled) {
mRedelivery = enabled;
}
@Override
public void onCreate() {
super.onCreate();
// 实例化了一个HandlerIntent用来处理请求
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
// 和HandlerIntent绑定的Looper
mServiceLooper = thread.getLooper();
// 利用和HandlerThread绑定Looper实例化Handler,就可以用这个Handler发送消息到HandlerThread中进行处理了。
mServiceHandler = new ServiceHandler(mServiceLooper);
}
@Override
public void onStart(@Nullable Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
// startId传给arg1,在上面的mServiceHandler的实现中会使用startId安全的停止服务
// startId每次启动service时如果service还存在,startId会不一样。
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
onStart(intent, startId);
// 根据mRedelivery来设置service意外终止时是否恢复。
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
@Override
public void onDestroy() {
// service终止时停止mServiceLooper消息循环
mServiceLooper.quit();
}
@Override
@Nullable
public IBinder onBind(Intent intent) {
return null;
}
// 我们自己写的类继承IntentService时需要复写这个方法,当我们的任务是耗时任务,导致第二次startservice时第一次的任务还没有完成,会导致第二个任务挂起,直到第一个任务完成,第二个任务才会执行,当所有任务都完成后,service就会停止。
@WorkerThread
protected abstract void onHandleIntent(@Nullable Intent intent);
}