IntentService是一个专门用来处理异步线程的一个服务,它内部创建了一个消息队列以及一个Handler对象,其它组件将Intent发送过来之后,IntentService会将这个Intent通过消息队列发送到工作线程,所以,我们可以放心大胆的在IntentService内部做耗时操作,而不必单独开启线程。

好,大概描述了下,我们看一下它的实现方式:

package android.app;import android.annotation.WorkerThread;
import android.content.Intent;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;...
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;}...@WorkerThreadprotected abstract void onHandleIntent(Intent intent);
}

将注释代码删除掉之后,真正的实现代码很少,现在将对这些代码一一说明,首先是onCreate方法:

onCreate方法主要做了以下事情:

创建HandlerThread线程并启动,使用HandlerThread对象所创建的Looper对象初始化ServiceHandler对象,这样,就可以通过ServiceHandler对象HandlerThread中的消息队列发送数据了,我们看看他们之间是如何实现的,首先是HandlerThread:

...
package android.os;...
public class HandlerThread extends Thread {int mPriority;int mTid = -1;Looper mLooper;public HandlerThread(String name) {super(name);mPriority = Process.THREAD_PRIORITY_DEFAULT;}...public HandlerThread(String name, int priority) {super(name);mPriority = priority;}...protected void onLooperPrepared() {}@Overridepublic void run() {mTid = Process.myTid();Looper.prepare();synchronized (this) {mLooper = Looper.myLooper();notifyAll();}Process.setThreadPriority(mPriority);onLooperPrepared();Looper.loop();mTid = -1;}...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;}...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;}...public int getThreadId() {return mTid;}
}

这个中的代码也不多,我们看主要的run方法:

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

run方法主要做了以下事情:

调用Looper.prepare();在当前线程中初始化一个Looper消息循环对象,并初始化了一个消息队列,拿到这个线程的Looper对象,然后开启消息循环访问模式。

接着回到IntentService的onCreate方法中,使用刚才的工作线程中的Looper对象来初始化ServiceHandler,使mServiceHandler对象向这个线程的Looper中发送消息。

准备工作做好之后,接下来的逻辑就简单了,其它组件通过startService方法,将Intent传递到这个服务中,会调用onStartCommand方法,onStartCommand调用onStart方法,而onStart方法会将接收到的Intent对象作为被传送的消息实体通过ServiceHandler发送到工作线程,然后我们如果使用的话,直接重写onHandleIntent就可以,onHandleIntent收到对象的时候已经处在工作线程当中。

我们在onHandleIntent方法中处理完毕任务之后,不必手动去调用stopSelf去停止服务,IntentService已经帮我们做了这样的处理。说到这里,可能你会有疑问,如果我在很短的时间内发送了多个请求,那么第一个请求处理完毕那服务不就终止了吗,后面的怎么处理呢,对于这个问题,需要详细了解一下stopSelf的说明:

如果我们现在工作在默认模式,同一时间只有一个Intent会被处理,如果在当前这个任务处理结束之前还有一个Intent请求过来的话,那它就不会被终止,它的原因与stopSelf有关系,stopSelf会判断终止的startId是否是最后发送过来的startId,所以,疑问解决了。

到这里基本的解释就说完了,有疑问欢迎留言。

IntentService解析相关推荐

  1. Android IntentService解析

    Android IntentService解析 在开发安卓应用程序时,除非你指定,否则绝大部分执行动作都运行UI线程中.这种机制会引发一些问题,因为耗时操作会妨碍用户交互行为.这会让用户感到懊恼,甚至 ...

  2. HandlerThread和IntentService源码解析

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

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

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

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

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

  5. Android - Intentservice源码解析

    https://blog.csdn.net/javazejian/article/details/52426425 转载于:https://www.cnblogs.com/qlky/p/1067562 ...

  6. Android之异步消息处理机制Handler源码解析

    转载请标明出处: http://blog.csdn.net/hai_qing_xu_kong/article/details/76083113 本文出自:[顾林海的博客] 个人开发的微信小程序,目前功 ...

  7. Android 中的线程及 AsyncTask(线程形态之一)解析一下

    科普一下 线程是操作系统调度的最小单元. 线程在android中是一个很重要的概念. 主线程 也叫 UI 线程 作用: 运行四大组件以及处理他们和用户交互. 子线程 作用; 执行耗时任务. 比如 I/ ...

  8. 透彻解析!字节跳动Android实习面试凉凉经,年薪超过80万!

    什么是Kotlin? Kotlin,如前面所说,它是JetBrains开发的基于JVM的语言.JetBrains因为创造了一个强大的Java开发IDE被大家所熟知.Android Studio,官方的 ...

  9. Android IntentService使用

    概述 演示使用Android 中IntentService的方法.IntentService一般情况下,用于后台处理一些耗资源的任务.本例子有演示使用这个IntentService类的代码,并可运行. ...

最新文章

  1. java 验证码图片识别_JavaSE图像验证码简单识别程序详解
  2. Oracle——redo+undo总结
  3. python二分法递归_python 【递归 及 二分法】
  4. Android设置text按钮,安卓基础控件使用(TextView、Button、ImageView、EditText)
  5. 转 Procrastination
  6. Oracle DBA课程系列笔记(5)
  7. 电竞高性能主机可以改云服务器吗,无缘主机平台 NBA 2K League电竞联赛将改用高性能PC...
  8. GIT上传代码Enumerating objects:类型报错解决,实测可用
  9. bzoj 1664: [Usaco2006 Open]County Fair Events 参加节日庆祝(DP)
  10. 超酷网页 Message Box 样式集合
  11. Android Messenger 跨进程通信
  12. 【路径规划】基于matlab遗传和模拟退火算法机器人路径规划【含Matlab源码 1206期】
  13. git branch/git checkout建立分支
  14. 2018百度之星程序设计大赛资格赛
  15. 利用c语言在屏幕上打印出窗口,南开19春学期(1709、1803、1809、1903)《计算机应用基捶在线作业...
  16. 清华紫光输入法linux,清华紫光输入法
  17. 如何找到刑事案件的辩点(律师角度)
  18. leetcode 39 : 给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
  19. ssh整合错误 0 nanoseconds spent acquiring 0 JDBC connections;
  20. 蛇形填数(语言:C语言)

热门文章

  1. Redis源码分析之anet网络通信的封装
  2. python函数名与变量名可以一样吗_python--第一类对象,函数名,变量名
  3. ES6(一)——字面量的增强、解构、let/const、块级作用域、暂时性死区
  4. Chapter7-4_來自獵人暗黑大陸的模型 GPT-3
  5. LeetCode 1408. 数组中的字符串匹配(暴力查找)
  6. LeetCode 409. 最长回文串(计数)
  7. LeetCode 274. H指数(排序,哈希)
  8. LeetCode 130. 被围绕的区域(图的BFS/DFS)
  9. LeetCode 204. 计数质数(质数的倍数不是质数)
  10. LeetCode 92. 反转链表 II(双指针)