IntentService与HandlerThread源码解析
来源:互联网 发布:2017流行语言网络词 编辑:程序博客网 时间:2024/06/15 16:35
一,写在前面
IntentService使用场景:需要在服务中执行耗时的任务,使用IntentService代替在Service中开启子线程。
HandlerThread:封装了Thread+Looper,但并没有封装Handler。它是一个线程,run方法中初始化了Looper对象,并开启消息循环。
IntentService:封装了HandlerThread+Handler的Service。
在阅读本篇文章前,建议先了解Handler机制的工作原理,本篇将不再对重复内容进行阐述。可参考文章
Android中Looper,MessageQueue,ThreadLocal源码解析
全面解析Android之Handler机制
二,使用IntentService
直接上代码,IntentService是一个抽象类,首先创建一个它的子类:
public class MyIntentService extends IntentService {public MyIntentService() {super("MyIntentService");}@Overrideprotected void onHandleIntent(Intent intent) {SystemClock.sleep(3000);String stringExtra = intent.getStringExtra("key");SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd hh:MM:ss");String time = format.format(new Date(System.currentTimeMillis()));Log.e("wcc", "onHandleIntent _ " + stringExtra + ", time is " + time);}@Overridepublic void onCreate() {super.onCreate();Log.e("wcc", "onCreate");}@Overridepublic void onStart(Intent intent, int startId) {super.onStart(intent, startId);Log.e("wcc", "onStart");}@Overridepublic void onDestroy() {super.onDestroy();Log.e("wcc", "onDestroy");}}接下来是启动服务的代码:
public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Intent intent = new Intent(this, MyIntentService.class);intent.putExtra("key", "value1");startService(intent);intent.putExtra("key", "value2");startService(intent);}}
启动了两次服务,每次存储在extra中的值都不一样。在onHandleIntent方法中执行耗时操作,并在各个生命周期方法中打印log。
打印log如下:
启动两次服务,onStart调用两次,onHandleIntent方法被调用两次且间隔3秒,最后onDestroy也被调用。为了解释上面这一现象,下面开始从源码角度分析IntentService工作原理。
三,HandlerThread源码分析
public class HandlerThread extends Thread { //...code @Override public void run() { mTid = Process.myTid(); Looper.prepare(); synchronized (this) { mLooper = Looper.myLooper(); notifyAll(); } Process.setThreadPriority(mPriority); onLooperPrepared(); Looper.loop(); mTid = -1; } //...code public Looper getLooper() { if (!isAlive()) { return null; } // If the thread has been started, wait until the looper has been created. synchronized (this) { while (isAlive() && mLooper == null) { try { wait(); } catch (InterruptedException e) { } } } return mLooper; } //...code}第8行,初始化Looper对象,并使用ThreadLocal存储该子线程的Looper。
第10行,从ThreadLocal中取出该线程的Looper对象,并赋值给变量mLooper。
第15行,调用Looper.loop()方法开启消息循环。
第21行,调用HandlerThread$getLooper返回变量mLooper,也就是获取该线程的Looper对象。
(对ThreadLocal,Looper不了解可以查看前面推荐的参考文章,这里不再重复描述)
小结:从上面可以看出,HandlerThread并不像名称展现的那样,它并没有封装Handler,而是封装了Thread,Looper。也就是说,HandlerThread是一个开启了消息循环的子线程。
注意:使用HandlerThread时,若不需要HandlerThread的时候,可以调用HandlerThread的quit/quitSafely方法结束消息循环,从而终止线程的执行。关于结束消息循环的原理,见文章 Android中Looper,MessageQueue,ThreadLocal源码解析 ,这里不再重复阐述。
四,IntentService源码分析
在调用startService启动服务的时候,会调用onCreate,onStart方法。
查看IntentService$onCreate,IntentService$onStart方法相关的源码:
@Override public void onCreate() { // TODO: It would be nice to have an option to hold a partial wakelock // during processing, and to have a static startService(Context, Intent) // method that would launch the service & hand off a wakelock. super.onCreate(); HandlerThread thread = new HandlerThread("IntentService[" + mName + "]"); thread.start(); mServiceLooper = thread.getLooper(); mServiceHandler = new ServiceHandler(mServiceLooper); } @Override public void onStart(Intent intent, int startId) { Message msg = mServiceHandler.obtainMessage(); msg.arg1 = startId; msg.obj = intent; mServiceHandler.sendMessage(msg); }第8行,创建HandlerThread对象,它是一个开启了消息循环的子线程。
第9行,调用HandlerThread$start方法启动线程,HandlerThread$run方法被调用,前面已对该方法进行分析,这里不再重复阐述。
第11行,获取HandlerThread中的Loooper对象,是一个子线程中的Looper对象。
第12行,创建一个变量mServiceLooper构造的Handler对象。
第17~19行,创建Message对象并设置字段arg1,obj的值;
第20行,使用Handler$sendMessage方法发送消息;
于是,查看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); } }第3行,调用Handler中Looper为参数的构造函数;
第8行,调用IntentService$onHandleIntent方法;
第9行,调用IntentService$stopSelf方法,停止服务,回调onDestroy方法。
查看IntentService$onHandleIntent方法源码:
protected abstract void onHandleIntent(Intent intent);onHandleIntent是一个抽象方法,需要我们自己重写该方法,并将耗时操作放在里面。
那么onHandleIntent为啥能执行耗时操作呢?
通过对Handler机制的理解可以知道:调用Looper$loop方法取出消息队列里的消息,并处理消息。因此消息的处理在哪个线程中完成取决于Looper.loop()在哪被调用,前面我们知道Looper的初始化,以及开启消息循环都是在子线程HandlerThread的run方法中完成。于是消息的处理是在子线程中执行,onHandleIntent就可以执行耗时操作。
五,最后
可以发现IntentService通过Handler机制将任务的执行,由主线程切换到Looper所在的子线程中执行。
若调用多个startService启动多个耗时任务,由于内部实现基于Handler机制,Looper是按照顺序来处理消息,因此这些耗时任务将按照启动的顺序依次执行。
另外,在handleMessage方法里调用stopSelf(startId)来停止服务,此外还有一个重载方法stopSelf()。区别:stopSelf(startId)停止服务,会等待消息队列里的消息全部处理完毕,再停止服务;而stopSelf()会立刻停止服务。
阅读全文
0 0
- IntentService与HandlerThread源码解析
- Handler与HandlerThread、IntentService源码解析
- 【Android】IntentService & HandlerThread源码解析
- 【Android】IntentService & HandlerThread源码解析
- HandlerThread 与 IntentService 源码分析
- HandlerThread与IntentService原理解析
- HandlerThread与IntentService完全解析
- Android HandlerThread和IntentService用法和源码解析
- Android多线程-HandlerThread用法与源码解析
- IntentService源码分析以及HandlerThread的用法
- 读IntentService、HandlerThread源码之浅析
- android IntentService Service HandlerThread 源码解读
- Android IntentService的使用与源码解析
- HandlerThread、IntentService
- HandlerThread源码解析
- HandlerThread 源码解析
- android HandlerThread源码解析
- HandlerThread 源码解析
- 继承学习一
- 虚拟机安装centos7.2后遗留网络问题解决方法
- 网弧与红鸟的一些bug
- numpy基础教程—矩阵的简单属性和方法
- Intellij IDEA 中一次性折叠所有Java代码的快捷键设置 collapse all
- IntentService与HandlerThread源码解析
- 逻辑回归的数学推导及java代码实现
- Python的30个编程技巧
- StringBuffer类的常用方法
- Django框架学习笔记(13.获取单表单数据的三种方式)
- PHP并行查询MySQL
- Meterpreter常用命令介绍
- SpringBoot配置Redis连接池
- 关于对equals的源码分析