Android-知识-017-Android多线程-IntentService-源码解析

72 阅读3分钟

IntentService 源码解析

IntentService 是 Android 提供的一个便捷工具,用于处理异步任务。其源码实现主要围绕 ServiceHandlerThread 构建,重点是通过一个后台线程按顺序处理传递的 Intent,并在任务完成后自动停止服务。


IntentService 工作流程概述

  1. 当调用 startService() 时:

    • Intent 会被加入到内部的任务队列中。
    • 使用 HandlerThread 在后台线程中逐个处理任务。
    • 最终调用 onHandleIntent(),开发者在此实现业务逻辑。
  2. 所有任务完成后,IntentService 会自动调用 stopSelf() 停止服务。

  3. 它的任务执行是串行的,每次只处理一个任务。


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); // 任务完成后停止服务
    }
}
  • ServiceHandlerIntentService 的核心:

    • 它通过 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);
        }
    }
}

工作流程总结

  1. 启动服务

    • 调用 startService() 时,IntentServiceIntent 封装为 Message,交由消息队列处理。
  2. 任务执行

    • HandlerThread 在线程中取出 Message,调用 onHandleIntent() 处理任务。
  3. 停止服务

    • 每次任务完成后,调用 stopSelf() 停止服务。
    • 所有任务完成后,自动停止 IntentService

优缺点

优点

  1. 简化异步任务处理

    • 不需要手动创建线程,内置线程池。
  2. 自动管理生命周期

    • 自动停止服务,减少资源浪费。
  3. 任务串行化

    • 任务按顺序执行,避免线程同步问题。

缺点

  1. 单线程

    • 所有任务共享一个线程,适合轻量级任务,任务多时可能导致延迟。
  2. 被 Android 8.0 限制

    • 后台执行受到限制,不适合长时间运行任务。

替代方案

  • WorkManager:推荐用于持久化任务。
  • JobIntentService:兼容 Android 8.0 的替代方案。
  • 线程池 + 协程:适用于复杂的异步任务场景。

总结

  • IntentService 是一个便捷工具,适合轻量级的一次性异步任务。
  • 源码结构简单,核心在于 HandlerThreadonHandleIntent()
  • 在现代 Android 开发中,应根据场景选择更灵活的替代方案(如 WorkManager 或协程)。