文章目录
  1. 1. IntentService用法
  2. 2. IntentService工作原理
  3. 3. Reference

今天这篇进不了花样劝退系列, 因为非常浅显, 就是一个为特定的常用场景而诞生的类.

我们常常会有这样的需求: 需要执行一个任务, 而这个任务可能跟我们主线程要做的事情无关, 完全可以异步执行, 并且它还有可能很耗时而不能在主线程做.
这种情况非常常见, 例如开始一个下载任务, 或者开启一个定时任务. 我们自己来做的话会怎么做呢? 通常是自行实现一个工作线程WorkerThread(当然你可以用ExecutorService生成一个线程池来帮你构造线程), 然后将任务扔给这个线程的工作队列, 这个线程则永不知疲倦地处理扔给它的所有任务.
显然这是个具有固定结构的编程模式, 意味着它完全可以提取出来成为公共库. 事实上线程池就是这么一个公共库, 但是在Android中可以更简单, 因为Android中有一个用于传递数据信息的数据结构Intent, 这意味着你不需要太过操心怎么传递数据. IntentService就是这么一个”工作线程”, 它依托于Service的基本结构, 使用Intent作为传递任务的信使.
顺便一提, 如果你只是临时想要执行一个任务, 那么AsyncTask可能会更合适.

IntentService用法

用法非常简单, 它是一个抽象类, 所以你只需要实现自己的子类, 实现下面列表中的抽象方法即可.

1
2
3
// 队列中每个Intent在处理时会调用本方法进行处理, 该方法运行在一个独立的工作线程上. 如果这个方法运行时间过长, 它会阻塞同个IntentService的后续请求. 所有队列中的请求处理完毕后, IntentService会自行停止, 所以无需再调用stopSelf
// Intent是通过startService(Intent)传进来到请求队列的
protected abstract void onHandleIntent(Intent intent);

然后你就可以使用startService或者bindService来启动或绑定服务.

IntentService的开始和普通Service相同, IntentService自己会处理好Service何时停止, 具体来说工作线程无任务时服务就会停止.

IntentService工作原理

如上文所述, IntentService就是把”异步任务处理器”这种模型以Service的形式实现的一个类. 从源码类的注释我们可以知道, 它自己实现了一个工作队列, 用的是Handler机制.
具体来说, 它为自己创建了一个HandlerThread线程, 这个线程里面会准备好自己的Looper队列. 它为自己创建了一个ServiceHandler内部类实例, 传入线程的Looper作为消息队列.

1
2
3
4
5
6
7
8
9
10
// in android/app/IntentService.java
@Override
public void onCreate() {
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();

mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}

ServiceHandler是个final类, 在handleMessage中调用onHandleIntent来处理Intent, 消息处理完后立即调用stopSelf看是否需要停止服务. 它也在onStart中将传入的Intent发送到消息队列.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// in android/app/IntentService.java
private final class ServiceHandler extends Handler {

@Override
public void handleMessage(Message msg) {
onHandleIntent((Intent)msg.obj); // 回调接口
stopSelf(msg.arg1); // 尝试停止服务
}
}

@Override
public void onStart(Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId; // 记录Id
msg.obj = intent; // 传递Intent
mServiceHandler.sendMessage(msg);
}

可以看到IntentService提供了默认实现来处理Service停止的生命周期, 工作线程和队列的创建和消息传递. 因此在扩展实现IntentService的时候, 如果不想自己处理这些过程, 最好在重写方法时调用超类同名方法(onBindonHandleIntent除外).

这个类的分析到这里就没了, 实在是庞大Android源码库中一股清流.

Reference

Android Fundamentals: IntentService Basics
source code

文章目录
  1. 1. IntentService用法
  2. 2. IntentService工作原理
  3. 3. Reference