1.IntentService 是什么

  1. 一个封装了HandlerThread和Handler的异步框架。
  2. 是一种特殊Service,继承自Service,是抽象类,必须创建子类才可以使用。
  3. 可用于执行后台耗时的任务,任务执行后会自动停止
  4. 具有高优先级(服务的原因),优先级比单纯的线程高很多,适合高优先级的后台任务,且不容易被系统杀死。
  5. 启动方式和Service一样。
  6. 可以多次启动,每个耗时操作都会以工作队列的方式在IntentService的onHandleIntent回调方法中执行。
  7. 串行执行。

2. IntentService的执行方式是串行还是并行

  串行

3. IntentService可以执行大量的耗时操作?

  1. 如果只有一个任务,是可以进行耗时操作的。
  2. 如果有很多任务,由于内部的HandlerThread是串行执行任务,会导致耗时操作阻塞了后续任务的执行。

4. IntentService和Service的区别

  1. 继承自Service
  2. IntentService任务执行完后会自动停止
  3. IntentService和Service优先级一致,比Thread高。
  4. Service处于主线程不能直接进行耗时操作; IntentService内部有HandlerThread,可以进行耗时操作。

5. IntentService的基本使用

1. 定义IntentService,实现onHandleIntent()'

public class LocalIntentService extends IntentService {
public static final String TAG="LocalIntentService";
public LocalIntentService( ) {
super(TAG);
} @Override
protected void onHandleIntent(Intent intent) {
String task=intent.getStringExtra("task");
Log.e(TAG, "onHandleIntent: task:"+task );
} @Override
public void onCreate() {
super.onCreate();
Log.e(TAG, "onCreate: " );
} @Override
public void onDestroy() {
super.onDestroy();
Log.e(TAG, "onDestroy: " );
}
}

  2.AndroidMainfest.xml 中声明ItnentService

<service android:name=".LocalIntentService"/>

  3. 开启IntentService

 findViewById(R.id.bt1).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent service=new Intent(MainActivity.this,LocalIntentService.class);
service.putExtra("task","task1");
startService(service); service.putExtra("task","task2");
startService(service); service.putExtra("task","task3");
startService(service); service.putExtra("task","task4");
startService(service); }
});

  

日志:

6. 源码和原理机制

1.IntetntService的OnCreate底层原理

  1. 构造了HandlerThread
  2. 并在每部保存了HandlerThread的Looper
  3. 并且使用该Looper创建了ServiceHandler
        //IntentService第一次启动调用
public void onCreate() {
super.onCreate();
//1. 创建一个HanlderThread
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
//2. 通过HanlderThread的Looper来构建Handler对象mServiceHandler
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);

2. IntentService的ServiceHandler

  1. HandlerThread会串行的取出任务并且执行,会调用ServiceHandler的handleMessage去处理任务。
  2. handlerMessage会去调用我们自定义的onHandleIntent
  3. 任务执行完毕后通过stopSelf(startId)停止Service。
  4. 任务结束后,在onDestory()中会退出HandlerThread中Looper的循环。

  

        //ServiceHandler接收并处理onStart()方法中发送的Msg
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
//1. 直接在onHandleIntent中处理(由子类实现)
onHandleIntent((Intent)msg.obj);
/**=================================================
* 2. 尝试停止服务(会等待所有消息都处理完毕后,才会停止)
* 不能采用stopSelf()——会立即停止服务
*================================================*/
stopSelf(msg.arg1); //会判断启动服务次数是否与startId相等
}
} public void onDestroy() {
mServiceLooper.quit();
}//销毁时会停止looper

  

3. IntentService内部去停止Service为什么不直接采用stopSelf()

  1. 采用stopSelf()——会立即停止服务
  2. 采用stopSelf(startId),会等所有消息全部处理完毕后,才会停止。会判断启动服务次数是否与startId相等

4. IntentService是如何停止HandlerThread的Looper消息循环的?

  1. 调用stopSelf(startId)后。
  2. 任务全部执行完,会停止服务,并且回调onDestory()。调用Looper的quit()方法即可

5. IntentService 多次startService会多次回调onHandleIntent()的内部流程?

  1. startService()->onStartCommand()->onStart()
  2. 通过HandlerThread的handler去发送消息。
  3. HandlerThread在处理任务时,会去调用onHandleIntent方法。
public abstract class IntentService extends Service {
private volatile Looper mServiceLooper;
private volatile ServiceHandler mServiceHandler;
...省略... //IntentService每次启动都会调用
public int onStartCommand(Intent intent, int flags, int startId) {
//3. 直接调用onStart
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
public void onStart(Intent intent, int startId) {
//4. 通过mServiceHandler发送一个消息(该消息会在HanlderThread中处理)
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
//2. 该Intent与startService(intent)中的Intent完全一致
protected abstract void onHandleIntent(Intent intent); }

  

6. IntentService的源码总结:

  1. IntentService通过发送消息的方式向HandlerThread请求执行任务
  2. HandlerThread中的looper是顺序处理消息,因此有多个后台任务时,都会按照外界发起的顺序排队执行
  3. 启动流程:onCreate()->onStartCommand()->onStart()
  4. 消息处理流程:ServiceHandler.handleMessage()->onHandleIntent()

参考:

IntentService详解

IntentService介绍的更多相关文章

  1. 【转载】Android IntentService使用全面介绍及源码解析

    一 IntentService介绍 IntentService定义的三个基本点:是什么?怎么用?如何work? 官方解释如下: //IntentService定义的三个基本点:是什么?怎么用?如何wo ...

  2. Android Service总结05 之IntentService

    Android Service总结05 之IntentService   版本 版本说明 发布时间 发布人 V1.0 添加了IntentService的介绍和示例 2013-03-17 Skywang ...

  3. Android Service详解

    service作为四大组件值得我们的更多的关注 在Android中,Activity主要负责前台页面的展示,Service主要负责需要长期运行的任务.例如,一个从service播放音乐的音乐播放器,应 ...

  4. Android Service总结03 之被启动的服务 -- Started Service

    Android Service总结03 之被启动的服务 -- Started Service 版本 版本说明 发布时间 发布人 V1.0 添加了Service的介绍和示例 2013-03-17 Sky ...

  5. Android IntentService使用介绍以及源码解析

    版权声明:本文出自汪磊的博客,转载请务必注明出处. 一.IntentService概述及使用举例 IntentService内部实现机制用到了HandlerThread,如果对HandlerThrea ...

  6. Android中的IntentService

    首先说下,其他概念:Android中的本地服务与远程服务是什么? 本地服务:LocalService 应用程序内部------startService远程服务:RemoteService androi ...

  7. Android之Notification介绍

    Notification就是在桌面的状态通知栏.这主要涉及三个主要类: Notification:设置通知的各个属性. NotificationManager:负责发送通知和取消通知 Notifica ...

  8. IntentService源码分析

    和HandlerThread一样,IntentService也是Android替我们封装的一个Helper类,用来简化开发流程的.接下来分析源码的时候 你就明白是怎么回事了.IntentService ...

  9. 【Android】IntentService & HandlerThread源码解析

    一.前言 在学习Service的时候,我们一定会知道IntentService:官方文档不止一次强调,Service本身是运行在主线程中的(详见:[Android]Service),而主线程中是不适合 ...

随机推荐

  1. 【详解】Linux的文件描述符fd与文件指针FILE*互相转换

    使用系统调用的时候用文件描述符(file descriptor,简称fd)的时候比较多,但是操作比较原始.C库函数在I/O上提供了一些方便的包装(比如格式化I/O.重定向),但是对细节的控制不够. 如 ...

  2. Java 迭代器 Iterator

    迭代器模式 迭代器模式(Iterator Pattern)是 Java 和 .Net 编程环境中非常常用的设计模式.这种模式用于顺序访问集合对象的元素,不需要知道集合对象的底层表示. 迭代器模式属于行 ...

  3. linux下今天遇到的问题

    之前由于测试需要,必须用mysql5.7的客户端, 现在由于产品完善,开始支持5.6,所以需要装5.6的客户端做测试,考虑到手工测试的效率及不可重复性,准备自动化执行原来的用例. 老的用例是用MySQ ...

  4. Java之MD5加密

    一.Message Digest Algorithm MD5(中文名为消息摘要算法第五版)为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护.该算法的文件号为RFC 1321(R.Riv ...

  5. 分布式锁实践(二)-ZooKeeper实现总结

    写在最前面 前几周写了篇 利用Redis实现分布式锁 ,今天简单总结下ZooKeeper实现分布式锁的过程.其实生产上我只用过Redis或者数据库的方式,之前还真没了解过ZooKeeper怎么实现分布 ...

  6. python打造漏洞补丁缺少检测

    前言: 当我们进行后渗透的时候,进行提权的时候 要识别被未打补丁的漏洞.来进行提权,从而 拿到管理员权限. 思路: 1.让使用者在cmd中打systeminfo命令.将补丁号 放入一个txt. 2.与 ...

  7. django-auth组件的权限管理

    一:自定义权限验证 1.在model中的Meta类自定义权限码 class WorkUser(models.Model): username = models.CharField(u'用户名', ma ...

  8. css 积累1

    1.position 取值. 通常的回答是 static.relative.absolute 和 fixed .当然,还有一个极少人了解的 sticky .其实,除此之外, CSS 属性通常还可以设置 ...

  9. 背景半透明rgba最佳实践

    by 一丝 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <tit ...

  10. JSP的动态导入

    <body> <!-- 动态引入 他们引入的相互独立的代码段 所以可以运行 代码段之间存在重复的变量 --> this is a test dy include 01 < ...