IntentService 使用及分析

IntentService

我们直接分析 IntentService 的源码,如下:

public abstract class IntentService extends Service {
    // Looper 对象
    private volatile Looper mServiceLooper;
    // Handler 对象
    private volatile ServiceHandler mServiceHandler;
    // 线程名称
    private String mName;
    private boolean mRedelivery;

    // Handler 内部类
    private final class ServiceHandler extends Handler {
        public ServiceHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            // 抽象方法,子类覆写来执行具体的业务逻辑
            onHandleIntent((Intent)msg.obj);
            // 根据 startId 来销毁自身,如果多次启动服务,最后一次才会销毁成功并回调 onDestroy
            stopSelf(msg.arg1);
        }
    }

    public IntentService(String name) {
        super();
        // 设置线程名称
        mName = name;
    }

    public void setIntentRedelivery(boolean enabled) {
        mRedelivery = enabled;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        // 创建 HandlerThread
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
        // 启动
        thread.start();

        mServiceLooper = thread.getLooper();
        // 创建 Handler
        mServiceHandler = new ServiceHandler(mServiceLooper);
    }

    @Override
    public void onStart(@Nullable Intent intent, int startId) {
        // 把相应信息封装成 Message 对象
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        msg.obj = intent;
        mServiceHandler.sendMessage(msg);
    }

    @Override
    public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
        // 直接调用 onStart 方法
        onStart(intent, startId);
        return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
    }

    @Override
    public void onDestroy() {
        // 退出循环,即销毁线程,回收资源
        mServiceLooper.quit();
    }

    @Override
    @Nullable
    public IBinder onBind(Intent intent) {
        // 直接返回 Null
        return null;
    }

    // 抽象方法,子类覆写来执行具体的业务逻辑
    @WorkerThread
    protected abstract void onHandleIntent(@Nullable Intent intent);
}

实现逻辑分析:

  1. 在 onCreate()方法中使用了一个 HandlerThread 来维护线程,传入 HandlerThread 内部维护的 Looper 来创建 ServiceHandler。

  2. 在onStart() 方法中将 Intent 和 startId 作为参数封装进了 Message ,并发送到 ServiceHandler 来处理。

  3. 在onStartCommand() 方法直接调用第二步的 onStart() 方法。

  4. 在 Handler 的 handleMessage() 回调中会调用抽象方法 onHandleIntent() ,执行完之后,会调用 stopSelf(startId) 方法来销毁自身,每次启动服务时 startId 都会不一样,只有当最近的 onStart() 的 startId 等于 stopSelf(startId) 时才会销毁成功并回调 onDestroy() 方法。比如说,如果只启动一次服务,第一次启动时,startId 为 1 ,那么执行 stopSelf(startId) 时的 startId 也为 1 ,则销毁成功。如果启动了两次服务,假设第二次启动时 startId 为 2 ,当处理第一次的逻辑时执行到stopSelf(startId) ,此时的 startId 为上一次的 startId,即为 1 ,则销毁不成功,继续处理第二次的处理逻辑,处理完才会销毁成功。也就是说,多次启动服务时,会顺序处理每次的请求,全部处理完后,才销毁服务 。

  5. 在 onDestroy() 中会退出循环,即销毁线程,回收资源。

IntentService 使用示例

自定义 IntentService 类:

public class TestIntentService extends IntentService {

    private static final String PARAM = "test";

    public TestIntentService() {
        super("TestIntentService");
    }

    public static void startIntentService(Context activity, String param) {
        Intent intent = new Intent(activity, TestIntentService.class);
        intent.putExtra(PARAM, param);
        activity.startService(intent);
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        Log.d("TestIntentService", "onHandleIntent 线程名称" + Thread.currentThread().getName());

        if (intent.getStringExtra(PARAM).equals("first")) {
            try {
                Log.d("TestIntentService", "first start");
                Thread.sleep(6000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } else {
            try {
                Log.d("TestIntentService", "again start");
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("TestIntentService", "onDestroy 线程名称" + Thread.currentThread().getName());
    }
}

启动服务:

if (isReadStart) {
               TestIntentService.startIntentService(this, "again");
           } else {
               TestIntentService.startIntentService(this, "first");
               isReadStart = true;
           }

打印日志:

D/TestIntentService: onHandleIntent 线程名称 IntentService[TestIntentService]
D/TestIntentService: first start
D/TestIntentService: onHandleIntent 线程名称 IntentService[TestIntentService]
D/TestIntentService: again start
D/TestIntentService: onDestroy 线程名称 main