今天主要总结一下IntentService的源码,里面是如何实现的,为什么IntentService在执行完耗时操作后会自动停止。

1.the service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work.

2.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. 同一时间只会执行一个进程。

一、IntentService的源码分析

我们知道在实现IntentService只需要把我们自己Service继承IntentService并实现里面的onHandleIntent方法就可以了。

我们带着两个小问题来看源码,

1.是否可以通过bindService来启动IntentService?(不行)

2.多次调用startService方法会启动多个IntentService吗?(不会)

3.为什么IntentService在执行完耗时操作后会自动停止?(主要在handleMessage里面有停止操作)

ps:源码还是比较简单的,为了方便学习我把源码都粘贴出来了。(*^▽^*)

package android.app;import android.annotation.WorkerThread;
import android.annotation.Nullable;
import android.content.Intent;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;/*** IntentService is a base class for {@link Service}s that handle asynchronous* requests (expressed as {@link Intent}s) on demand.  Clients send requests* through {@link android.content.Context#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.** <p>This "work queue processor" pattern is commonly used to offload tasks* from an application's main thread.  The IntentService class exists to* simplify this pattern and take care of the mechanics.  To use it, extend* IntentService and implement {@link #onHandleIntent(Intent)}.  IntentService* will receive the Intents, launch a worker thread, and stop the service as* appropriate.** <p>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.** <p class="note"><b>Note:</b> IntentService is subject to all the* <a href="/preview/features/background.html">background execution limits</a>* imposed with Android 8.0 (API level 26). In most cases, you are better off* using {@link android.support.v4.app.JobIntentService}, which uses jobs* instead of services when running on Android 8.0 or higher.* </p>** <div class="special reference">* <h3>Developer Guides</h3>* <p>For a detailed discussion about how to create services, read the* <a href="{@docRoot}guide/components/services.html">Services</a> developer* guide.</p>* </div>** @see android.support.v4.app.JobIntentService* @see android.os.AsyncTask*/
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,执行完后会调用stopSelf来停止。onHandleIntent((Intent)msg.obj);stopSelf(msg.arg1);}}/*** Creates an IntentService.  Invoked by your subclass's constructor.** @param name Used to name the worker thread, important only for debugging.*/public IntentService(String name) {super();mName = name;}/*** Sets intent redelivery preferences.  Usually called from the constructor* with your preferred semantics.** <p>If enabled is true,* {@link #onStartCommand(Intent, int, int)} will return* {@link Service#START_REDELIVER_INTENT}, so if this process dies before* {@link #onHandleIntent(Intent)} returns, the process will be restarted* and the intent redelivered.  If multiple Intents have been sent, only* the most recent one is guaranteed to be redelivered.** <p>If enabled is false (the default),* {@link #onStartCommand(Intent, int, int)} will return* {@link Service#START_NOT_STICKY}, and if the process dies, the Intent* dies along with it.*/public void setIntentRedelivery(boolean enabled) {mRedelivery = enabled;}@Overridepublic 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();//创建一个HandlerThreadHandlerThread thread = new HandlerThread("IntentService[" + mName + "]");thread.start();//获取当前thread的Lopper对象mServiceLooper = thread.getLooper();mServiceHandler = new ServiceHandler(mServiceLooper);}@Overridepublic void onStart(@Nullable Intent intent, int startId) {//多次调用startService并不会启动多个Service,只会发送多的消息到消息队列中。Message msg = mServiceHandler.obtainMessage();msg.arg1 = startId;msg.obj = intent;mServiceHandler.sendMessage(msg);}/*** You should not override this method for your IntentService. Instead,* override {@link #onHandleIntent}, which the system calls when the IntentService* receives a start request.* @see android.app.Service#onStartCommand*/@Overridepublic int onStartCommand(@Nullable Intent intent, int flags, int startId) {//启动IntentService会直接调用onStartCommand,在这个里面会调用onStart方法去发送消息//这也就是为什么调用startService方法来启动IntentService,因为会调用onStartCommand//当然上面也写了,这个方法不用你重写。onStart(intent, startId);return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;}@Overridepublic void onDestroy() {mServiceLooper.quit();}/*** Unless you provide binding for your service, you don't need to implement this* method, because the default implementation returns null.* @see android.app.Service#onBind*/@Override@Nullablepublic IBinder onBind(Intent intent) {return null;}//下面的方法也说了,onHandleIntent在worker线程中工作,一次只能一个,当所有发送的请求都执行完,就是停止自己。/*** 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 {@link #stopSelf}.** @param intent The value passed to {@link*               android.content.Context#startService(Intent)}.*               This may be null if the service is being restarted after*               its process has gone away; see*               {@link android.app.Service#onStartCommand}*               for details.*/@WorkerThreadprotected abstract void onHandleIntent(@Nullable Intent intent);
}

二、总结

其实Intentservice源码相对比较简单,但是我们也需要了解里面是如果执行的。这样也方便我们被别人问到可以更流畅的回答。

2.多次调用startService方法会启动多个IntentService吗?(不会)

由于onCreate()方法只会调用一次,所以只会创建一个工作线程,当多次调用startService的时候onStartCommand和onStart会调用很多次)但不会创建新的工作线程,只是会把消息发送到消息队列中等待执行,所以多次调用IntentService会按照顺序执行的。当然了如果服务停止了会调用OnDestory会把所有消息移除,后续的时间也不会被执行了。

【安卓学习积累】IntentService的源码分析相关推荐

  1. 深度学习库 caffe使用 源码分析 依赖库分析 caffe glog gflags openBlas prototxt yolo_darknet 转 caffe

    深度学习库 caffe使用 源码分析 依赖库分析 caffe glog gflags openBlas 本文github链接 yolo_darknet 转 caffe caffe 安装 Caffe代码 ...

  2. golang学习之negroni/gizp源码分析

    在 Go 语言里,Negroni 是一个很地道的 Web 中间件,它是一个具备微型.非嵌入式.鼓励使用原生 net/http 库特征的中间件.利用它地Use功能,我们可以很简单地自定义中间件并使用.其 ...

  3. 了不起的 Webpack HMR 学习指南(含源码分析)

    学习时间:2020.06.14 学习章节:<Webpack HMR 原理解析> 一.HMR 介绍 Hot Module Replacement(以下简称:HMR 模块热替换)是 Webpa ...

  4. FFmpeg 源码学习(一):avformat_open_input 源码分析

    一.源码方法参数分析 下面是avformat_open_input的方法及参数: /** * Open an input stream and read the header. The codecs ...

  5. Combres库 学习小结以及部分源码分析

    昨天看到有博客园网友发布了一篇关于<使用Combres 库 ASP.NET 网站优化>的文章,觉得是个挺不错的脚本优化的类库,而且目前我的项目公务员考试应战平台也有使用到Js以及css合并 ...

  6. Netty学习笔记 - 1 (带源码分析部分)

    2021年12月 北京 xxd 一.Netty是什么 Netty 是由 JBOSS 提供的一个 Java 开源框架,现为 Github 上的独立项目. Netty 是一个异步的.基于事件驱动的网络应用 ...

  7. boost学习之boost::lock_guard源码分析

    boost::lock_guard可以说是一种比boost::unique_lock轻量级的lock, 简单一些场景可以用它就行了.源码如下: template<typename Mutex&g ...

  8. STL学习(自学手册+源码分析)之RB -tree

    1.1 RB-tree 1.1.1 RB-tree主体部分 template <class Key, class Value, class KeyOfValue, class Compare,c ...

  9. EventBus源码分析

    简介 前面我学习了如何使用EventBus,还有了解了EventBus的特性,那么接下来我们一起来学习EventBus的源码,查看EventBus的源码,看看EventBus给我们带来什么惊喜以及编程 ...

最新文章

  1. Outlook for Mac v15.36(170606)发布:新增收藏夹功能
  2. Android Socket编程
  3. flink配置+停止flink中的job
  4. 关于git pull机制和游戏开发热更新思考
  5. Go Web编程--给自己写的服务器添加错误和访问日志
  6. VC++注册,卸载OCX控件,以及判断是否注册
  7. Go本地浏览Web服务器
  8. Tuxedo中间件介绍
  9. Axure RP 10 安装方法
  10. 轻巧实用的web ssh工具使用笔记——WGCLOUD
  11. 剑灵灵动区服务器位置,《剑灵》这波电二合区,属实让我脑壳疼
  12. 201809-3-元素选择器
  13. Opencv Python 综合练习1---读取银行卡卡号
  14. Python 批量将.xlsx文件转为.xls文件
  15. 计算机专业江苏考研,22考研,计算机专业江苏地区有哪些性价比高又好考的学校,快收藏吧!...
  16. 数据预处理--上采样(过采样)与下采样(降采样)
  17. 01-物联网(环保管家)(一)温湿度与plc通信具体实现步骤
  18. 用C语言开发NES游戏(CC65) 前言
  19. 从技术、服务到共创 声网Agora构建RTC生态
  20. 第一个 古典花纹文字

热门文章

  1. antd vue 多个下拉 联动_antd中select下拉框值为对象选中的问题
  2. Ubuntu18.04 搜狗输入法不能输入中文问题、
  3. Java 安全编程详解
  4. java timsort_JDK(二)JDK1.8源码分析【排序】timsort
  5. RPC通信协议远程服务调用(25)Java全栈
  6. 用 Python 高效处理大文件
  7. vscode python无法跳转到函数定义
  8. HCIP之OSPF(五)
  9. Xcode8 支持 iOS7及以下版本
  10. arm linux免驱usb声卡,arm linux利用alsa驱动并使用usb音频设备