IntentService是什么?

这篇文章是之前就写好的,一直没有整理出来,这几天有空正好整理发布一下。

我们知道Service可以让我们在后台处理一些事情,但是Service实际上也是主线程,所以执行长耗时任务时依然会ANR,只不过ANR触发时间要比前台长。一般我们会在Service中开启一个子线程去完成耗时任务。

而IntentService就是解决这个问题的,它是Service的一个抽象子类,需要实现onHandleIntent,代码在这个函数中执行。它与Service最大的不同就是默认开启一个子线程,而onHandleIntent就是在子线程中执行的。

所以IntentService就是一个自带子线程的Service。

那么它是如何实现的,我们通过它的源码来简单分析一下。

线程的创建

IntentService的源码其实不多,先来看看它的onCreate函数

@Override
public void onCreate() {super.onCreate();HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");thread.start();mServiceLooper = thread.getLooper();mServiceHandler = new ServiceHandler(mServiceLooper);
}

在onCreate中会创建并启动一个HandlerThread。这个HandlerThread是Thread的一个子类,通过它的源码可以看到实际上就是默认绑定开启了looper,它的run函数如下:

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

可以看到绑定并启动了一个looper,而它的其他函数则都与looper和handler的操作有关,这里不一一看了。

回到onCreate中,接下来的代码则是通过HandlerThread的looper创建了一个ServiceHandler,这是一个内部类,源码如下:

private final class ServiceHandler extends Handler {public ServiceHandler(Looper looper) {super(looper);}@Overridepublic void handleMessage(Message msg) {onHandleIntent((Intent)msg.obj);stopSelf(msg.arg1);}
}

可以看到在handleMessage中调用了onHandleIntent,这样函数中的代码就在这个HandlerThread的子线程中运行。

然后执行了stopSelf函数,这个函数是Service的,用于停止服务的,与context的stopService效果是一样的。

也就是说IntentService执行onHandleIntent后就会试图停止服务,但是这里还有一些逻辑,注意传參是msg.arg1,这个很重要,后面会再详谈。

线程运行

通过上面我们知道,IntentService创建时开启一个线程并启动一个looper,并且通过ServiceHandler来执行代码。但是想要执行onHandleIntent,一定需要sendMessage,那么在哪send的呢?

答案是在Service的start周期中,如下:

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

可以看到在onStart中组合了一个msg并send,这样就实现了服务一启动就自动执行onHandleIntent
注意msg的arg1参数赋值是startId,结合上面所说的就是执行onHandleIntent后会执行stopSelf(startId)

上面我们说过stopSelf会试图停止服务,为什么是试图而不是一定,关键就是startId这里。

只有当stopSelf函数的startId与Service当前的startId相同,才会停止服务,主要是针对多次startService的情况。

当我们多次startService的时候,startId会自动递增,并且保存最后一个startId。

所以多次startServiceonHandleIntent会执行多次,因为前几次执行到stopSelf时startId不同,只有当最后一个执行完后才真正的停止服务。

但是注意,在onBind函数中并没有sendMessage,所以IntentService需要使用start的方式,bind的方式由于不会走onStart这个周期,所以onHandleIntent不会执行。

退出线程

在创建线程时默认开启了looper,looper其实就是一个死循环,所以这个线程会一直阻塞。那么IntentService如何退出这个线程?

IntentService详解相关推荐

  1. Android 多线程之IntentService 完全详解

    转载请注明出处(万分感谢!): http://blog.csdn.net/javazejian/article/details/52426425 出自[zejian的博客] 关联文章: Android ...

  2. Android进阶笔记:Messenger源码详解

    Messenger可以理解为一个是用于发送消息的一个类用法也很多,这里主要分析一下再跨进程的情况下Messenger的实现流程与源码分析.相信结合前面两篇关于aidl解析文章能够更好的对aidl有一个 ...

  3. java stopself_Android Service详解(二)---StartService

    一丶概述 启动服务由另一个组件通过调用 startService() 启动,这会导致调用服务的 onStartCommand() 方法. 服务启动之后,其生命周期即独立于启动它的组件,并且可以在后台无 ...

  4. android最全面试题71道题 详解

    Android面试题 1. 下列哪些语句关于内存回收的说明是正确的? (b ) A. 程序员必须创建一个线程来释放内存 B. 内存回收程序负责释放无用内存 C. 内存回收程序允许程序员直接释放内存 D ...

  5. 关于Android Service真正的完全详解,你需要知道的一切

    转载请注明出处(万分感谢!):  http://blog.csdn.net/javazejian/article/details/52709857  出自[zejian的博客]   Service全部 ...

  6. android gridview控件使用详解_作为Android 开发者该如何进阶?

    经常在简书和微信上收到一些同学的私信,说自己马上毕业或者已经毕业一年,从事Android开发相关的工作,现在不知道要学习什么东西了.或者说自己也在摸索着学习,但是不知道学习的路线对不对,感觉很迷茫,想 ...

  7. Android App优化之ANR详解

    引言 背景:Android App优化, 要怎么做? Android App优化之性能分析工具 Android App优化之提升你的App启动速度之理论基础 Android App优化之提升你的App ...

  8. android demo示例代码,Android Service demo例子使用详解(示例代码)

    Android Service demo例子使用详解\ 概述 Service 是 Android 的四大组件之一,它主要的作用是后台执行操作,Activity 属于带有 UI 界面跟用户进行交互,而 ...

  9. Android UI 测试框架Espresso详解

    Android UI 测试框架Espresso详解 1. Espresso测试框架 2.提供Intents Espresso 2.1.安装 2.2.为Espresso配置Gradle构建文件 2.3. ...

最新文章

  1. maven <skip></skip>属性
  2. 云安全,到底是什么一回事?
  3. 自定义Interpolator
  4. gdb调试fork多进程
  5. 优酷背后的大数据秘密:资源弹性,可支撑EB级存储
  6. 模块间同步消息队列的设计
  7. 【C++ primer】第七章 函数-C++的编程模块
  8. 如何在一个日期值上加上分钟值得到新的日期
  9. quartz job基本运用
  10. vlc 网页插件的 使用与控制 API
  11. ucore源码分析step1
  12. js获取当前农历时间
  13. 你不知道的JavaScript(上卷)- - 书本知识点记录
  14. 微信开发平台第三方平台86004无效微信号
  15. 通过Java访问数据库---JDBC
  16. HDF5 header version 1.10.4与HDF5 library 1.10.5冲突解决办法记录
  17. 阻止路由跳转得方式_vue路由拦截及页面跳转设置的方法介绍
  18. 拿到CCIE证书两年后
  19. 孙悟空的坚定目标 (孙悟空有何深仇大恨大闹天宫)
  20. 产品设计-9.制作产品流程图

热门文章

  1. CTime,Systemtime的比较还有转换成日期格式。
  2. 47、Windows驱动程序模型笔记(五),内存管理
  3. 学习:ASP.NET中App_Code,App_Data等文件夹的作用(转)
  4. 百度Google搜索框中,你不知道的变化
  5. python六十四课——高阶函数练习题(一)
  6. 团队-团队编程项目作业名称-需求分析
  7. YARN应用场景、原理与资源调度
  8. android studio 导入一个已有的android studio project作为lib使用
  9. sap router maintenance
  10. nhibernate3 linq的的select 操作