IntentService 介绍

IntentService 是一种特殊的 Service,它继承了 Service 并且它是一个抽象类,因此必须创建它的子类才能够使用 IntentService。它可用于执行后台耗时任务,当任务执行完成后它会自动停止,在资源不足时,系统会对一些被认为时无用的资源给清理掉,由于它是 Service 的原因,它的优先级比单纯的线程的优先级高很多,不容易被系统杀死(清理掉),所以它适合执行一些高优先级的后台任务。在实现上,IntentService 封装了 Handlerhread 和 Handler。

HandlerThread 继承了 Thread,它是一种可以使用 Handler 的 Thread。它的实现是通过在run()方法中通过Looper.prepare()来创建消息队列,并通过Looper.loop()方法来开启消息循环, 它的内部对Thread 的 run 方法进行重写,通过Handler的消息方式(Looper循环)来通知HandlerThread执行一个具体的任务。

@Override
public void run() {mTid = Process.myTid();Looper.prepare();synchronized (this) {mLooper = Looper.myLooper();notifyAll();}Process.setThreadPriority(mPriority);onLooperPrepared();Looper.loop();mTid = -1;
}

在明确了不需要使用HandlerThread的时,可以通过它的quit或者quitSafely方法来终止线程的执行

public boolean quit() {Looper looper = getLooper();if (looper != null) {looper.quit();return true;}return false;
}public boolean quitSafely() {Looper looper = getLooper();if (looper != null) {looper.quitSafely();return true;}return false;
}

这两个方法的区别是:

quit()
使用此方法可能是不安全的,因为在Looper队列终止之前可能无法传递某些消息。

quitSafely()
使用此方法可能是安全的,因为一旦已经传递消息,队列中的所有剩余消息被处理,方法就会终止。然而,在循环终止之前,延迟的消息将在未来的到期时间内不传递。

从源码来分析 IntentService 的执行顺序

在onCreate()初始化HandlerThread和ServiceHandler,用于在后面调用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);
}

每次启动服务都会调用一次onStartCommand()方法,并且它会调用onStart()

@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {onStart(intent, startId);return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}

在onStart()中发送消息

@Override
public void onStart(@Nullable Intent intent, int startId) {Message msg = mServiceHandler.obtainMessage();msg.arg1 = startId;msg.obj = intent;mServiceHandler.sendMessage(msg);
}

后台任务是顺序执行的
因为 Handler 中的 Looper 是顺序处理消息。

任务执行完成之后结束服务:

private final class ServiceHandler extends Handler {public ServiceHandler(Looper looper) {super(looper);}@Overridepublic void handleMessage(Message msg) {onHandleIntent((Intent)msg.obj);// 使用 stopSelf(msg.arg1); 而不使用 stopSelf();// 是因为 stopSelf() 会立即停止服务,// 而 stopSelf(msg.arg1); 在停止服务前会先判断最近启动服务的次数是否和 startId 相等// 如果相等就历经停止服务,不想动则不停止服务stopSelf(msg.arg1);}
}

IntentService 使用

创建一个实例继承自 IntentService

public class TestIntentService extends IntentService {private static final String TAG = "TestIntentService";public TestIntentService() {super(TAG);Log.e(TAG, "TestIntentService: " );}@Overridepublic void onCreate() {super.onCreate();Log.e(TAG, "onCreate: " );}@Overrideprotected void onHandleIntent(@Nullable Intent intent) {String taskAction = intent.getStringExtra("task_action");SystemClock.sleep(3000);Log.e(TAG, "onHandleIntent: "+taskAction);}@Overridepublic void onDestroy() {Log.e(TAG, "onDestroy: service destory" );super.onDestroy();}
}

注册服务
在AndroidMainfest.xml中注册服务

<service android:name=".thread.TestIntentService"/>

开启服务

Intent intent = new Intent(CallBackTestActivity.this, TestIntentService.class);
intent.putExtra("task_action","com.dx.action.TASK1");
// 开启第一个服务
startService(intent);
intent.putExtra("task_action","com.dx.action.TASK2");
// 开启第二个服务
startService(intent);
intent.putExtra("task_action","com.dx.action.TASK3");
// 开启第三个服务
startService(intent);

输出结果是:

从截图中的时间,以及输出顺序正好验证了上面的叙述!ok,完工~

原创作者:龙衣袭,原文链接:https://www.jianshu.com/p/92c8a4451bb0

欢迎关注我的微信公众号「码农突围」,分享Python、Java、大数据、机器学习、人工智能等技术,关注码农技术提升•职场突围•思维跃迁,20万+码农成长充电第一站,陪有梦想的你一起成长。

异步处理老司机:IntentService 源码分析相关推荐

  1. Android面试题Service,Android面试题-IntentService源码分析

    自定义控件 联网 工具 数据库 源码分析相关面试题 Activity相关面试题 Service相关面试题 与XMPP相关面试题 与性能优化相关面试题 与登录相关面试题 与开发相关面试题 与人事相关面试 ...

  2. Android 异步处理之IntentService源码分析

    本文授权发布公众号[刘桂林],星球[Hi Android] 今天介绍一下IntentService,他和Service其实差不多,只是内部实现了一个HandlerThread,这点我们看源码其实就可以 ...

  3. 【spring】spring异步执行的使用与源码分析

    在实际的开发过程中,有些业务逻辑使用异步的方式处理更为合理.比如在某个业务逻辑中,需要把一些数据存入到redis缓存中,这个操作只是一个辅助的功能,成功或者失败对主业务并不会产生根本影响,这个过程可以 ...

  4. 网络编程之 哈希表原理讲解 来自老司机的源码

    鉴于博主很久没由跟新过数据结构的内容了,所以博主打算给大家讲解一下哈希表的操作 下面的内容来自于一位老司机 martin的源码,博主在这里借用一下,目的是突出哈希表的原理,明天博主就周末了,也能腾出时 ...

  5. 老司机php源码,JeRuen

    PHP扩展开发系列01 - 我要成为一名老司机 1. 关于扩展的教程貌似挺全了,为啥还写?记录下我写扩展的历程 自认为会写的更容易理解 我的宗旨就是 "先用再识" 代码写着写着就知 ...

  6. netty源码分析系列——EventLoop

    2019独角兽企业重金招聘Python工程师标准>>> 前言 EventLoop也是netty作为一个事件驱动架构的网络框架的重要组成部分,netty主要通过它来实现异步编程,从前面 ...

  7. Android HandlerThread 源码分析

    HandlerThread 简介: 我们知道Thread线程是一次性消费品,当Thread线程执行完一个耗时的任务之后,线程就会被自动销毁了.如果此时我们又有一 个耗时任务需要执行,我们不得不重新创建 ...

  8. OkHttpClient源码分析(一)—— 同步、异步请求分析和Dispatcher的任务调度

    OkHttpClient同步请求的执行流程和源码分析 同步请求示例 OkHttpClient okHttpClient = new OkHttpClient.Builder().readTimeout ...

  9. 【OkHttp】OkHttp 源码分析 ( 同步 / 异步 Request 请求执行原理分析 )

    OkHttp 系列文章目录 [OkHttp]OkHttp 简介 ( OkHttp 框架特性 | Http 版本简介 ) [OkHttp]Android 项目导入 OkHttp ( 配置依赖 | 配置 ...

  10. Thrift异步IO服务器源码分析

    http://yanyiwu.com/work/2014/12/06/thrift-tnonblockingserver-analysis.html 最近在使用 libevent 开发项目,想起之前写 ...

最新文章

  1. 周志华:严肃的研究者就不该去触碰强人工智能
  2. python和c哪个适合入门-编程入门选什么语言好?C 语言还是Python ?为你解析
  3. C++学习笔记第二天:几个知识点
  4. Linux查看文件内容命令:cat, tail, head, more, less
  5. java写的教育管理的项目_干货分享|推荐12款适合做Java后台管理系统的项目
  6. homeassistant mysql_HomeAssistant学习笔记docker安装的ha更换数据库
  7. GitHub和Microsoft TFS对比有什么优势
  8. 如何使用计算机中的导出,(excel在电脑的哪个文件里?)excel怎么把查找的导出
  9. [置顶] Embedded Server:像写main函数一样写Web Server
  10. 【两种方式】用python和ENVI画出高光谱遥感影像的3D立体图
  11. vscode推荐编程字体
  12. Python-爬取历史地震数据并可视化
  13. mysql 唯一约束和唯一索引_谈谈唯一约束和唯一索引
  14. Centos7安装Docker,阿里源,网易镜像
  15. 51单片机入门学习------环境搭建
  16. Oracle卸载的全过程
  17. WordArt与everything联用生成含中文的词云
  18. Java读取txt文件,并且对其文件内容进行统计排序
  19. 谷歌app使用的是什么字体_Google字体无法在中国使用-如何修复
  20. 华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典

热门文章

  1. 计算机速录学什么,学速录需要哪些能力
  2. linux grep正则表达式,linux-正则表达式与grep命令
  3. 论文笔记_SLAM_VINS-Mono: A Robust and Versatile Monocular Visual-Inertial State Estimator
  4. opencv数字图像处理(3)- 图像平滑与锐化
  5. 中缀表达式转后缀表达式(非常简单易懂)
  6. 安装vs2008之后系统好像变慢了?
  7. 钉钉自定义机器人 发送文本 换行 \n无效果
  8. JDBC03 利用JDBC实现事务提交与回滚【调用Connection中的方法实现事务管理】
  9. 0917 词法分析程序(java版)
  10. 如何建立开发环境可以让开发人员快捷开发出模型的原型