原址
   对比: IntentService是Service的子类,和Service不同的是,IntentService内部已经实现绑定好一个工作线程,因此,在IntentService中可以直接执行耗时操作,这样就省下了我们要在Service中人为创建线程来处理耗时操作的时间,减轻了工作量。

IntentService是可以处理异步请求的Service。每次所有的请求都会被放置在Looper管理的消息队列中。当消息队列不为空的时候,会依次取出请求并交给工作线程处理,直至所有的请求被处理完成。线程结束后将会自动停止。需要注意的是IntentService每次只能有一个任务被工作线程执行(唯一)在工作。下面我们直接分析相关源码:

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);}@Overridepublic void handleMessage(Message msg) {onHandleIntent((Intent)msg.obj);stopSelf(msg.arg1);}}public IntentService(String name) {super();mName = name;}public void setIntentRedelivery(boolean enabled) {mRedelivery = enabled;}@Overridepublic void onCreate() {super.onCreate();HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");thread.start();mServiceLooper = thread.getLooper();mServiceHandler = new ServiceHandler(mServiceLooper);}@Overridepublic void onStart(Intent intent, int startId) {Message msg = mServiceHandler.obtainMessage();msg.arg1 = startId;msg.obj = intent;mServiceHandler.sendMessage(msg);}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {onStart(intent, startId);return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;}@Overridepublic void onDestroy() {mServiceLooper.quit();}@Overridepublic IBinder onBind(Intent intent) {return null;}protected abstract void onHandleIntent(Intent intent);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67

IntentService是由Looper,Handler,Service共同组合而成。 
1、IntentService在创建时执行onCreate()。在创建HandlerThread线程后,获取当前线程的Looper对象来初始化mServiceLooper,接着创建mServiceHandler。在此过程中工作线程和mServiceHandler进行了绑定。

2、启动IntentService时,产生一条Message(携带startId和Intent),并将该Message发送到MessageQueue中。然后,Looper一旦发现该Message,则将该Message交给mServiceHandler中的handleMessage处理。

3、接着会调用onHandleIntent()来处理。这个方法是抽象方法,需要我们在子类中重写该方法实现相关的处理逻辑。任务一旦完成就会调用stopSelf()来结束指定的工作线程。值得注意的是onHandleIntent()是运行在工作线程当中的。

4、当所有的工作完成之后,执行onDestory()方法,其中通过调用mServiceLooper.quit()来在服务结束时停止Looper。


总结: 
IntentService是基于消息队列(MessageQueue)的服务,,每次启动服务并不会马上处理工作,而是首先创建对应的Looper、Handler。任务的执行顺序即queue队列Message的顺序(排队执行)。任务一旦完成,将会自行停止。因此其使用范围多在以下几种情况:

更新客户端版本 
需要在后台执行单任务 
多个允许异步执行的后台任务(无前后顺序和时间顺序的要求) 
优缺点: 
使用方便,避开了我们自己需要Service中创建线程。 
由于只有一个工作线程,所有任务的执行都需要排队,因为不适合对任务并发的情况。


简单测试:

public class MainActivity extends Activity {@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Log.d("IntentService", "ui thread name:"+Thread.currentThread().getName());for(int i=0;i<10;i++)startService(new Intent(this, AsyncService.class));}}public class AsyncService extends IntentService {public AsyncService() {super("async");}@Overrideprotected void onHandleIntent(Intent intent) {try {Log.d("IntentService", "work thread name:"+Thread.currentThread().getName());Thread.sleep(7000);} catch (InterruptedException e) {e.printStackTrace();}}}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

运行结果: 
1、耗时操作未产生ANR 
2、输出的Log日志为: 

深入理解IntentService相关推荐

  1. HandlerThread和IntentService源码解析

    简介 首先我们先来了解HandlerThread和IntentService是什么,以及为什么要将这两者放在一起分析. HandlerThread: HandlerThread 其实是Handler ...

  2. Handler消息机制(九):IntentService源码解析

    作者:jtsky 链接:https://www.jianshu.com/p/0a150ec09a32 简介 首先我们先来了解HandlerThread和IntentService是什么,以及为什么要将 ...

  3. 【Android】期末简答题

    1.Activity类中定义了7个回调方法,分别是什么? 我的答案: onCreate()这个方法你已经看到过很多次了,每个活动中我们都重写了这个方法,它会在活动第一次被创建的时候调用.你应该在这个方 ...

  4. Android面试题整理(源自鸿洋大神公众号【201803】的一篇BAT面试题推送)

    三月,想必各位程序员GG 此刻想要的,莫过于一篇面试宝典.鄙人不才,也从未系统的刷过面试题,以鸿洋大哥一篇面试题为引,略加整理,希望能帮到各位不知道看什么小伙伴.(大部分知识都是有答案的). 原文链接 ...

  5. android service使用handle,android中对Looper、HandlerThread、IntentService的理解及使用方法...

    消息队列处理模型 容器保存事件,队列 涉及到角色: 类 功能 MessageQueue 存放消息 Looper 轮循消息队列,从中取出消息 Thread 处理消息 Message 消息 Handler ...

  6. Android开发之Service与IntentService的区别与使用场景(源代码剖析)

    因为最大部分的service不需要同时处理多个请求(处理多个请求是一个比较危险的多线程的场景),这样在在这种情况下呢,最好使用IntentService类如果你实现你的服务. 使用intentServ ...

  7. Service IntentService区别 (面试)

    依然记得自己当初没有真正的工作经验的时候的日子,满北京跑,没有人要.妈的,现在就想问,还有谁!想想真解气.不提了. 曾经有个面试官问我service 和IntentService的区别.当时自己模模糊 ...

  8. Android Service、IntentService,Service和组件间通信

    Service组件 Service 和Activity 一样同为Android 的四大组件之一,并且他们都有各自的生命周期,要想掌握Service 的用法,那就要了解Service 的生命周期有哪些方 ...

  9. Android多线程之IntentService源码解析

    想要了解 IntentService 的工作原理需要先对 Android 系统中以 Handler.Looper.MessageQueue 组成的异步消息处理机制以及 HandlerThread 有所 ...

最新文章

  1. python打包软件后报错 :SyntaxError: Non-UTF-8 code starting with ‘\x90‘ in file 的原因及解决方法
  2. DevOps:软件架构师行动指南2.2 云的特性
  3. win10系统Jmeter下载安装详解
  4. 谐波小波 matlab,基于谐波小波的电力系统谐波分析
  5. CSS练习中|无序列表中,<li>的小黑点如何替换为图片(菜鸡趣味学习,细节到每一步)
  6. 我的世界服务器存档的文件夹,我的世界存档在哪个文件夹
  7. oracle autovue是什么软件,AutoVue
  8. python办公室自动化之office颜值担当-PPT
  9. OSChina 周一乱弹 —— 花式遛狗法
  10. Windows环境下的视图之间切换快捷键及几个常用快捷键
  11. CAD如何创建图层并绘制图形
  12. uni-app云打包失败
  13. 【Linux】命令别名与历史命令(alise\history)
  14. 字符串数组大写小写互相转换
  15. 失落的帝国:盛大业务大收缩
  16. vivo计算机有没有弧度计算公式,x 23手机背面弧度大不大??
  17. Java面向对象系列[v1.0.0][类加载器]
  18. MIC29302WU-TR高电流、高精度、低压差的稳压器
  19. 大数据营销模型思路架构
  20. MPLAB-IDE-C语言编程代码实例-分析

热门文章

  1. swing Ctrl+S 保存配置
  2. golang windows下杀进程
  3. RFID将成为物联网革命的首战
  4. Tiff – 比较两种字体差异
  5. Tensorflow学习笔记-第二节程序结构
  6. NMS 原理和c++实现,已测试通过
  7. 归并排序的java代码_归并排序的原理及java代码实现
  8. php 课程节次周次提取,用PHP写一个最简单的解释器Part5(计算器最后一节,下节开始如何写个脚本语言)...
  9. 异步Udp监听关闭 出现异常,访问已释放的资源或者其他错误的解决方法
  10. python-5 函数