前言
在上一篇文章中我们分析了HandlerThread的源码,同时也提到过HandlerThread的使用场景之一就是IntentService。通过查看源码我们就可以知道IntentService中封住了HandlerThread和Handler,那它是如何实现的呢?接下来我们来分析一下 。首先我们来提出几个问题,在分析完源码后再来思考是否能完美的回答出以下几个问题。
- IntentService的工作原理是什么?
- IntentService与Thread的区别是什么?
IntentService本质
public abstract class IntentService extends Service {
//......
}
复制代码
从继承关系来看,IntentService继承Service。说明它具有Service的一切特性,并且本身还是一个抽象类。既然IntentService是一个Service,那么它适合执行一些优先级较高的任务。而且IntentService封装了Handler和HandlerThread,它可以执行耗时操作。
构造方法
public IntentService(String name) {
super();
mName = name;
}
复制代码
onCreate()
@Override
public void onCreate() {
super.onCreate();
//1
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
//2
mServiceLooper = thread.getLooper();
//3
mServiceHandler = new ServiceHandler(mServiceLooper);
}
复制代码
1
在onCreate()方法中创建了一个HandlerThread,并执行了它的start()方法。
2
通过getLooper()方法获取了HandlerThread的Looper对象,并赋值给了mServiceLooper。
private volatile Looper mServiceLooper;
复制代码
3
最后通过mServiceLooper,也就是HandlerThread的Looper对象,创建了ServiceHandler。从名字上就可以知道ServiceHandler就是IntentService使用的Handler,ServiceHandler源码如下。
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);
}
}
复制代码
小结
通过对IntentService的onCreate()方法分析,我们可以得知该方法主要作了三件事。
- 创建HandlerThread
- 获取HandlerThread的Looper对象
- 创建ServiceHandler
onStartCommand()
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
复制代码
我们在来看一下onStartCommand()方法,可以看出在里面调用了onStart()方法,我们继续往下看。
onStart()
@Override
public void onStart(@Nullable Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
复制代码
通过源码可以看出在onStart()方法内部是通过ServiceHandler发送了一个消息,那肯定是发给HandlerThread,由HandlerThread来处理消息。
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);
}
}
复制代码
当ServiceHandler收到消息时,会调用onHandleIntent()方法,最后调用stopSelf(msg.arg1)方法停止服务。如果存在多个任务需要IntentService执行,那么是顺序执行还是同时执行呢?因为Handler中的Looper对象是顺序执行的,也就是说IntentService也是顺序执行,多个任务需要排队处理。
stopSelf(int startId)
public final void stopSelf(int startId) {
if (mActivityManager == null) {
return;
}
try {
mActivityManager.stopServiceToken(
new ComponentName(this, mClassName), mToken, startId);
} catch (RemoteException ex) {
}
}
复制代码
在上面我们说过调用stopSelf(int startId)方法会结束服务,在Service源码中有两个stopSelf()方法。分别是带参数的和不带参数的,上面的方法就是带参数的。主要作用是当IntentService中所有的任务全部处理完毕后,才会尝试去停止服务。
stopSelf()
public final void stopSelf() {
stopSelf(-1);
}
复制代码
总结
通过本篇文章,我们大概了解IntentService的工作原理。也知道了它与Thread的区别,以及它的几个重要方法。
参考资料
- 《Android艺术探索》