Android查缺补漏(线程篇)-- IntentService的源码浅析
本文作者:CodingBlock 文章链接:http://www.cnblogs.com/codingblock/p/8975114.html
在Android中有两个比较容易弄混的概念,Service和Thread,我们都知道这两个东西都可以执行后台任务,但要注意的是Service是跑在主线程中的,如果不做特殊处理是会阻塞主线程的,而IntentService正好弥补了这一点,在《Android查缺补漏--Service和IntentService》这篇博文中已经简单介绍过了IntentService的基本用法,本篇博文会将对IntentService的原理做一个简单的分析。
一、IntentService的初始化分析
IntentService是一种服务,可以很方便的执行后台异步任务,采用HandlerThread执行任务,当任务执行完毕后,IntentService自动退出。
相比于普通的Service,IntentService继承了Service,并在其内部创建了HandlerThread和Handler,其中HandlerThread用于执行耗时任务,可以查看IntentService的onCreate方法的源码:
@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);
}
通过源码可以看到,IntentService在onCreate()方法中创建了一个HandlerThread,并为这个HandlerThread绑定了一个Handler(ServiceHandler)。
注:HandlerThread 是一种具有消息循环的线程,在其内部可以使用handler,其底层实现是内部创建了Looper的线程。
二、IntentService启动任务过程分析
外界首次调用startService方法来启动IntentService时,就会触发onCreate()方法,完成上面操作。
当外界每次触发onStart方法时,就会在此方法里面通过ServiceHandler向HandlerThread线程发送消息,onStart方法的源码如下:
@Override
public void onStart(@Nullable Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
当上面源码中的mServiceHandler.sendMessage方法发送完消息后,在ServiceHandler的handlerMessage方法中就会调用onHandleIntent方法来执行我们创建的异步任务,当执行完onHandleIntent中的代码就会使用stopSelf(msg.arg1)尝试关闭Service。
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);
}
}
由于HandlerThread只是一个单线程,所以是串行处理任务。
(stopSelf():立即停止服务。stopSelf(int startId):尝试停止服务,当还有其他消息未处理,会等待其他消息处理完后再关闭)
三、IntentService优势
- 由于IntentService是一个服务,所以在执行后台任务时不容易被杀死,想比而言单纯的开启一个线程来执行后台任务,由于这个进程中没有活动的四大组件,所以非常容易被系统杀死。
- 其实在普通的Service中开启一个线程也能达到IntentService的效果,只是这样我们用起来更方便,那么在Service中开启线程或者使用IntentService相比在Activity中开启线程有什么优势呢?在Activity中开启了线程后,当退出了Activity时如果线程中的任务没有执行完毕,线程是不会退出的。而此时再打开同一个Activity又会创建一个新的线程,就是说在Activity中创建的线程不会随着Activity的销毁而销毁,是不可控的。而如果我们在Service中创建了线程,然后如果线程中的任务没有执行完毕,我们可以让Service一直运行在后台去承载这个线程,这样的话我们以后在想操作这个线程的话就可以在外界通过bindService的方式再绑定这个Service,从而可以控制运行在这个Service中的线程。
本文作者:CodingBlock 文章链接:http://www.cnblogs.com/codingblock/p/8975114.html
本文为博客园首发并已同步授权给腾讯云·云+社区!
Android查缺补漏(线程篇)-- IntentService的源码浅析的更多相关文章
- Android查缺补漏--Service和IntentService
Service的运行不依赖界面,即使程序被切换到后台,Service仍然能够保持正常运行.当某个应用程序进程被杀掉时,所有依赖于该进程的Service也会停止运行. Service 分为启动状态和绑定 ...
- Android查缺补漏(View篇)--自定义 View 的基本流程
View是Android很重要的一部分,常用的View有Button.TextView.EditView.ListView.GridView.各种layout等等,开发者通过对这些View的各种组合以 ...
- Android查缺补漏(IPC篇)-- 进程间通讯基础知识热身
本文作者:CodingBlock 文章链接:http://www.cnblogs.com/codingblock/p/8479282.html 在Android中进程间通信是比较难的一部分,同时又非常 ...
- Android查缺补漏(IPC篇)-- 款进程通讯之AIDL详解
本文作者:CodingBlock 文章链接:http://www.cnblogs.com/codingblock/p/8436529.html 进程间通讯篇系列文章目录: Android查缺补漏(IP ...
- Android查缺补漏(IPC篇)-- 进程间通讯之Socket简介及示例
本文作者:CodingBlock 文章链接:http://www.cnblogs.com/codingblock/p/8425736.html 进程间通讯篇系列文章目录: Android查缺补漏(IP ...
- Android查缺补漏(IPC篇)-- 进程间通讯之AIDL详解
本文作者:CodingBlock 文章链接:http://www.cnblogs.com/codingblock/p/8436529.html 进程间通讯篇系列文章目录: Android查缺补漏(IP ...
- Android查缺补漏(View篇)--事件分发机制源码分析
在上一篇博文中分析了事件分发的流程及规则,本篇会从源码的角度更进一步理解事件分发机制的原理,如果对事件分发规则还不太清楚的童鞋,建议先看一下上一篇博文 <Android查缺补漏(View篇)-- ...
- Android查缺补漏(IPC篇)-- Bundle、文件共享、ContentProvider、Messenger四种进程间通讯介绍
本文作者:CodingBlock 文章链接:http://www.cnblogs.com/codingblock/p/8387752.html 进程间通讯篇系列文章目录: Android查缺补漏(IP ...
- Android查缺补漏(线程篇)-- AsyncTask的使用及原理详细分析
本文作者:CodingBlock 文章链接:http://www.cnblogs.com/codingblock/p/8515304.html 一.AsyncTask的使用 AsyncTask是一种轻 ...
随机推荐
- vue中的vue-cli
在前面的学习过程中我相信你们已经对vue有了一定的了解,现在我们来看一下vue中的vue-cli. 学习这个我们首先需要的是node环境的,如果你的网络环境慢的话建议安装淘宝镜像,在cmd中输入 np ...
- [转]python 模块 chardet下载及介绍
来源:http://blog.csdn.net/tianzhu123/article/details/8187470/ 在处理字符串时,常常会遇到不知道字符串是何种编码,如果不知道字符串的编码就不 ...
- SQL发音考(搜寻SQL-86标准)
据我观察,中国的开发者创造了一种独特的SQL发音:/'sɜːkl/,既好听,又好读,挺好的.但是今年我开始做数据库相关的工作,作为一个专业人士,决定对SQL发音进行一些考证. 直接说结论吧,很多人沿用 ...
- 音频增益响度分析 ReplayGain 附完整C代码示例
人们所熟知的图像方面的3A算法有: AF自动对焦(Automatic Focus)自动对焦即调节摄像头焦距自动得到清晰的图像的过程 AE自动曝光(Automatic Exposure)自动曝光的是为了 ...
- 高并发下,log4j日志打印行数导致的内存溢出问题
log4j日志打印时,如果将行数打印出来,在调用量极大的情况下,会出现内存溢出问题. log4j打印日志,打印行数时,行数是通过一个一个exception抛出,再极高调用量的情况下,内存会因为exce ...
- How to preview html file in our browser at sublime text?
sublime preview html.md open In Browser what should we do if we want to preview html file in our bro ...
- NKOJ4191 Trie树
问题描述 字母(Trie)树是一个表示一个字符串集合中所有字符串的前缀的数据结构,其有如下特征: 1.树的每一条边表示字母表中的一个字母 2.树根表示一个空的前缀 3.树上所有其他的节点都表示一个 ...
- [SDOI2010]代码拍卖会
题目描述 随着iPig在P++语言上的造诣日益提升,他形成了自己一套完整的代码库.猪王国想参加POI的童鞋们都争先恐后问iPig索要代码库.iPig不想把代码库给所有想要的小猪,只想给其中的一部分既关 ...
- [AHOI2009]中国象棋
题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法.大家肯定很清楚,在中国象棋中炮的行走方式是 ...
- [Apio2009]Atm
题目描述 输入 第一行包含两个整数N.M.N表示路口的个数,M表示道路条数.接下来M行,每行两个整数,这两个整数都在1到N之间,第i+1行的两个整数表示第i条道路的起点和终点的路口编号.接下来N行,每 ...