分析的IntentService源码为API-25版本
IntentService属于Service
IntentService继承自Service,那么它的结构就和Service一样。
![](https://img.haomeiwen.com/i1717635/826d564cd0c6d233.png)
这个不需多讲。但在使用上与Service有点不同,可以说简化版的Service。有点类似Handler与AsyTask的关系。
IntentService的使用
Intent serviceIntent = new Intent(this, ParseIntentService.class);
startService(serviceIntent);
上面代码就是开启一个IntentService服务。开启之后就不用管理它了。这就是刚才说的简化版的Service。这篇文章的重点其实就是这里:IntentService为什么是简化的Service
上面的ParseIntentService继承IntentService,重写了onHandleIntent()方法。
IntentService源码
IntentService的源码不多就只有百来行
![](https://img.haomeiwen.com/i1717635/01da7f4b51127b91.png)
解析下这里的代码:
出现Looper和Handler。
-
ServiceHandler handleMessage()方法,调用完onHandleIntent();方法后stopSelf()即停止服务。所以上面说IntentService开启服务后不需要管它,因为它调用完ServiceHandler的handleMessage()方法后就会停止服务。
都知道Handler的handleMessage()不是Handler自己调用的,是有发送信息,handleMessage()就会被调用。那么现在看看哪里发送信息。 -
Looper 在后面涉及到会介绍
IntentService的onCreate()方法
都知道Service和Activity类似都会有相关生命周期的方法。当上门的代码开启服务,系统就会调用Service的onCreate()
![](https://img.haomeiwen.com/i1717635/65b7aeef14f4e160.png)
通过onCreat()方法可以得出下边的结论:
- HandlerThread 一个线程类开启一个工作线程
- mServiceLooper为工作线程的Looper
- ServiceHandler为工作线程的Handler
首先Handler是主线程的Handler还是工作线程的Handler主要看它的Looper,而ServiceHandler的Looper为工作线程下的Looper,所以ServiceHandler属于工作线程的Handler。判断哪个线程的Handler,主要因为看handlerMessage()方法在哪个线程执行。
其次为什么说mServiceLooper为工作线程的Looper,
image.png
截图是HandlerThread的run()方法。可以看到mServiceLooper是在run()里面得到的,所以mServiceLooper为工作线程的Looper.。
HandlerThread 一个线程类这个就不用说了。
HandlerThread
该类其实是干嘛的呢?简单来说,它就是帮我们创建一个工作线程的Looper,Looper的作用就是轮询我们的消息分发机制(这里不细说,细说又是一篇了。。。)。详细了解HandlerThread 可以看下面这篇文章
为什么要用HandlerThread,怎么用?
为什么出现Handler,Looper这些消息分发类别的类?
![](https://img.haomeiwen.com/i1717635/c82efc490d9ebad1.png)
主要因为IntentService的onStart()方法中发送了消息,上面创建onCreat()时,构建了ServiceHandler对象。通过Handler消息分发机制,处理抽象方法onHandleIntent();
使用IntentService,重写onHandleIntent()方法
- 第一,创建一个类继承IntentService,实现onHandleIntent();
public class ParseIntentService extends IntentService {
public ParseIntentService() {
super("ParseIntentService");
}
/**
* 该方法在工作线程上调用
* */
@Override
protected void onHandleIntent(@Nullable Intent intent) {
//TODO 需要在服务做的事情
}
});
}
}
- 第二,创建Intent,调用startService()方法。
Intent serviceIntent = new Intent(this, ParseIntentService.class);
startService(serviceIntent);
总结
- onHandleIntent()方法是在工作线程上的;不用执行更新UI的工作
- IntentService里面已经有工作线程无需开启新的工作线程。
这里想说一下:如果你在onHandleIntent()通过Retrofit调用接口,而又使用OkHttp的,建议使用Service不建议用IntentService。因为OkHttp已经帮我们创建了工作线程。这样又用IntentService的工作线程又用IntentService实际上是一种内存消耗。 - 这点给自己一个笔记通过这个IntentService最主要认识了在工作线程中的Handler;HandlerThread管理工作线程的Looper
网友评论