IntentService 源码解析
IntentService 是 Android 提供的一个便捷工具,用于处理异步任务。其源码实现主要围绕 Service 和 HandlerThread 构建,重点是通过一个后台线程按顺序处理传递的 Intent,并在任务完成后自动停止服务。
IntentService 工作流程概述
-
当调用
startService()时:Intent会被加入到内部的任务队列中。- 使用
HandlerThread在后台线程中逐个处理任务。 - 最终调用
onHandleIntent(),开发者在此实现业务逻辑。
-
所有任务完成后,
IntentService会自动调用stopSelf()停止服务。 -
它的任务执行是串行的,每次只处理一个任务。
IntentService 源码结构
1. 构造方法
java
复制代码
public IntentService(String name) {
super();
mName = name; // 服务线程的名称
}
- 构造方法需要传递一个线程名称,用于创建
HandlerThread。 - 这个名称主要是用于调试或日志的标识。
2. onCreate()
java
复制代码
@Override
public void onCreate() {
super.onCreate();
// 创建一个 HandlerThread
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
// 获取 HandlerThread 的 Looper,关联到 mServiceLooper
mServiceLooper = thread.getLooper();
// 将 Looper 传递给 ServiceHandler,用于处理消息队列
mServiceHandler = new ServiceHandler(mServiceLooper);
}
-
HandlerThread:
HandlerThread是一个带有消息队列的线程,专用于处理后台任务。
-
mServiceLooper:
HandlerThread启动后,获取其Looper,用于消息分发。
-
ServiceHandler:
- 继承自
Handler,负责在onHandleIntent()中执行任务。
- 继承自
3. onStartCommand()
java
复制代码
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId; // 服务的启动 ID
msg.obj = intent; // 启动服务时的 Intent
mServiceHandler.sendMessage(msg); // 发送消息,加入队列
return START_NOT_STICKY;
}
-
将
Intent封装成Message,交给Handler的消息队列处理。 -
START_NOT_STICKY:
- 表示系统在服务被异常终止时,不会自动重启服务。
4. ServiceHandler
java
复制代码
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
onHandleIntent((Intent) msg.obj); // 调用开发者实现的核心方法
stopSelf(msg.arg1); // 任务完成后停止服务
}
}
-
ServiceHandler是IntentService的核心:- 它通过
Looper在子线程中处理消息。 - 调用
onHandleIntent()执行开发者提供的逻辑。 - 每次任务完成后,通过
stopSelf()停止服务。
- 它通过
5. onHandleIntent(Intent intent)
java
复制代码
protected abstract void onHandleIntent(@Nullable Intent intent);
- 这是开发者需要实现的抽象方法。
- 运行在后台线程,用于处理耗时任务。
6. onDestroy()
java
复制代码
@Override
public void onDestroy() {
mServiceLooper.quit(); // 释放 Looper
}
- 在服务销毁时,停止
HandlerThread的消息循环,释放资源。
IntentService 完整源码结构
java
复制代码
public abstract class IntentService extends Service {
private volatile Looper mServiceLooper;
private volatile ServiceHandler mServiceHandler;
private String mName;
public IntentService(String name) {
super();
mName = name;
}
@Override
public void onCreate() {
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
@Override
public void onStart(@Nullable Intent intent, int startId) {
onStartCommand(intent, 0, startId);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
return START_NOT_STICKY;
}
@Override
public void onDestroy() {
mServiceLooper.quit();
}
protected abstract void onHandleIntent(@Nullable Intent intent);
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
onHandleIntent((Intent) msg.obj);
stopSelf(msg.arg1);
}
}
}
工作流程总结
-
启动服务:
- 调用
startService()时,IntentService将Intent封装为Message,交由消息队列处理。
- 调用
-
任务执行:
HandlerThread在线程中取出Message,调用onHandleIntent()处理任务。
-
停止服务:
- 每次任务完成后,调用
stopSelf()停止服务。 - 所有任务完成后,自动停止
IntentService。
- 每次任务完成后,调用
优缺点
优点:
-
简化异步任务处理:
- 不需要手动创建线程,内置线程池。
-
自动管理生命周期:
- 自动停止服务,减少资源浪费。
-
任务串行化:
- 任务按顺序执行,避免线程同步问题。
缺点:
-
单线程:
- 所有任务共享一个线程,适合轻量级任务,任务多时可能导致延迟。
-
被 Android 8.0 限制:
- 后台执行受到限制,不适合长时间运行任务。
替代方案
- WorkManager:推荐用于持久化任务。
- JobIntentService:兼容 Android 8.0 的替代方案。
- 线程池 + 协程:适用于复杂的异步任务场景。
总结
- IntentService 是一个便捷工具,适合轻量级的一次性异步任务。
- 源码结构简单,核心在于
HandlerThread和onHandleIntent()。 - 在现代 Android 开发中,应根据场景选择更灵活的替代方案(如
WorkManager或协程)。