前言
在上一篇文章中我们分析了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艺术探索》