什么是 IntentService
service 默认也运行在 UI 线程,所以里面不能直接做耗时操作,要做耗时操作还得开启子线程来做。
IntentService 就是一个 Service, 只不过里面给你默认开启了一个子线程来处理所有的 intent 请求。
而多次调用 startService 时所有请求都会放到这个子线程中一个接一个的按顺序执行,等所有的请求都处理完毕后 service 会自动销毁。
一句话描述就是用一个子线程来依次处理各个请求,请求按顺序一个接一个执行。按顺序执行是通过 Looper 队列实现的。
看看源码就清晰了
/**
* 这段注释应该多读几遍
* IntentService is a base class for Service that handle asynchronous
* requests (expressed as Intent) on demand. Clients send requests
* through startService(Intent)} calls; the
* service is started as needed, handles each Intent in turn using a worker
* thread, and stops itself when it runs out of work.
*
* All requests are handled on a single worker thread -- they may take as
* long as necessary (and will not block the application's main loop), but
* only one request will be processed at a time.
*/
public abstract class IntentService extends Service {
private volatile Looper mServiceLooper;
private volatile ServiceHandler mServiceHandler;
private String mName;
private boolean mRedelivery; private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
} @Override
public void handleMessage(Message msg) {
// handleMessage 还是在 onCreate 中启动的子线程中执行,因为 Looper 在哪个线程 handler 就在哪个线程执行
// 消息队列保证了所有请求按顺序执行
onHandleIntent((Intent)msg.obj); // 这里貌似停止了服务, 其实不是只有当 startId 等于最后一次启动服务时的 startId 时服务才会销毁
stopSelf(msg.arg1);
}
} public IntentService(String name) {
super();
mName = name;
} @Override
public void onCreate() {
super.onCreate();
// onCreate 时启动一个带有 Looper 的子线程
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start(); mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
} @Override
public void onStart(Intent intent, int startId) {
// 每次 onStart 时都发送一个消息到消息队列中等待执行
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
} @Override
public int onStartCommand(Intent intent, int flags, int startId) {
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
} @Override
public void onDestroy() {
mServiceLooper.quit();
} @Override
public IBinder onBind(Intent intent) {
return null;
} /**
* 这段注释也应该多读几遍
* This method is invoked on the worker thread with a request to process.
* Only one Intent is processed at a time, but the processing happens on a
* worker thread that runs independently from other application logic.
* So, if this code takes a long time, it will hold up other requests to
* the same IntentService, but it will not hold up anything else.
* When all requests have been handled, the IntentService stops itself,
* so you should not call stopSelf.
*/
@WorkerThread
protected abstract void onHandleIntent(Intent intent);
}
看似简单其实里面东西挺多,发现网上好多人理解有误区,有人认为是每 start 一次都开启一个 worker 线程, 其实不是如果 service 还没有销毁多次调用
都只有一个线程来按顺序来处理请求。
什么是 IntentService的更多相关文章
- 什么时候用IntentService
IntentService是继承自Service类的,在执行耗时操作时,其实,只需要在service中的onStartCommand(主线程)新启一个线程即可,那IntentService什么时候用来 ...
- IntentService
http://developer.android.com/training/run-background-service/index.html IntentService 只是简单的对Service做 ...
- 缩略信息是: sending message to a Handler on a dead thread 我是用IntentService时报的
稍微纤细一点儿的信息是: Handler (android.os.Handler) {215ddea8} sending message to a Handler on a dead thread. ...
- HandlerThread和IntentService
HandlerThread 为什么要使用HandlerThread? 我们经常使用的Handler来处理消息,其中使用Looper来对消息队列进行轮询,并且默认是发生在主线程中,这可能会引起UI线程的 ...
- android 中IntentService的作用及使用
IntentService是继承于Service并处理异步请求的一个类,在IntentService内有一个工作线程来处理耗时操作,启动IntentService的方式和启动传统Service一样,同 ...
- Android中的IntentService
首先说下,其他概念:Android中的本地服务与远程服务是什么? 本地服务:LocalService 应用程序内部------startService远程服务:RemoteService androi ...
- Android中Services之异步IntentService
IntentService:异步处理服务,新开一个线程:handlerThread在线程中发消息,然后接受处理完成后,会清理线程,并且关掉服务. IntentService有以下特点: (1) 它创 ...
- IntentService源码分析
和HandlerThread一样,IntentService也是Android替我们封装的一个Helper类,用来简化开发流程的.接下来分析源码的时候 你就明白是怎么回事了.IntentService ...
- Android Service 与 IntentService
Service 中的耗时操作必须 在 Thread中进行: IntentService 则直接在 onHandleIntent()方法中进行
- Android IntentService完全解析 当Service遇到Handler
一 概述 大家都清楚,在Android的开发中,凡是遇到耗时的操作尽可能的会交给Service去做,比如我们上传多张图,上传的过程用户可能将应用置于后台,然后干别的去了,我们的Activity就很可能 ...
随机推荐
- 小白科普之JavaScript的数组
一.与其他语言数据的比较 相同点:有序列表 不同点:js的数组的每一项可以保存任何类型的数据:数组的大小是可以动态调整的 二.数组创建的两种方法 1) var colors = new ...
- [转]linux awk命令详解
原文链接 : http://blog.chinaunix.net/uid-23302288-id-3785105.html awk是行处理器: 相比较屏幕处理的优点,在处理庞大文件时不会出现内存溢 ...
- Android学习笔记之打钩显示输入的密码
利用EditText作为密码输入框是个不错的选择(只需设置输入类型为textPassword即可),保密且无需担心被盗取.但有时用户也不知道自己输入的是否正确,这时就应该提供一个“显示密码”的复选框, ...
- Linux文件与目录常用命令
目录常用命令: cd:切换目录 pwd:显示当前目录 mkdir:新建一个目录 rmdir:删除一个空的目录 ## cd 命令几种常用方法: cd ~username 切换到用户username的主文 ...
- Coursera台大机器学习课程笔记15 -- Three Learning Principles
这节课是最后一节,讲的是做机器学习的三个原则. 第一个是Occan's razor,即越简单越好.接着解释了什么是简单的hypothesis,什么是简单的model.关于为什么越简单越好,林老师从大致 ...
- 使用JDBC获取各数据库的Meta信息——表以及对应的列
先贴代码,作为草稿: 第一个是工具类, MapUtil.java [java] view plain copy import java.util.ArrayList; import java.util ...
- 关于DCMTK3.6.0源代码编译的总结
1.DCMTK cmake出来的代码是一样的.MT和MD版本的区别在于DCMTK工程下的每个子工程的代码生成中的MT还是MD,只要修改成为相应的值就可以了. 2.依赖包的选择.依赖包必须与上面中所说的 ...
- Flip Game I && II
Flip Game I Problem Description: You are playing the following Flip Game with your friend: Given a s ...
- HDU 5044(2014 ACM-ICPC上海网络赛)
题意:给定一个树形图,节点10^5,有两种操作,一种是把某两点间路径(路径必定唯一)上所有点的权值增加一个固定值. 另一种也是相同操作,不同的是给边加权值.操作次数10^5.求操作过后,每个点和每条边 ...
- cocos2dx混合模式应用———制作新手引导高亮区域
先看下效果 制造这个椭圆高亮区域所使用原图是 附上代码 bool HelloWorld::init() { ////////////////////////////// // 1. super ini ...