Android IntentService源码解析

本文深入解析Android中的IntentService,探讨其初始化过程、如何通过Handler实现串行任务处理、自动停止机制及请求重传功能,适合对IntentService基本使用有一定了解的开发者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        本文是对Android IntentService的源码解析,对其基本使用还不了解的朋友可以先快速入门IntentService再来阅读本文。

初始化

        类似于Activity,Service也有onCreate、onDestory等用于管理生命周期的方法,先来看看IntentService初始化的源码。

private volatile Looper mServiceLooper;
private volatile ServiceHandler mServiceHandler;

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

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

        IntentService是串行处理任务的,说到串行处理,Handler就是最典型的例子。从源码可以看出IntentService也用到了Handler。这里简单说一下Handler,Handler由如下几个部分组成。

HandlerThread:特殊的线程类,自带Looper,Handler必须运行在一个有Looper的线程上。
Looper:内部维护着一个消息队列,串行地取出消息进行处理。Looper是线程局部变量,也就是说每个HandlerThread都有属于自己的Looper(通过ThreadLocal来实现)。
Message:用于装载消息,消息传递完以后可以被Looper回收再利用(回收到Message池)。
MessageQueue:收到的消息在此排队等待Looper来处理。

        对Handler源码感兴趣的朋友可以看看我写的这篇文章。回到刚刚的源码,代码1先创建一个HandlerThread,这个线程就是IntentService处理请求的线程。代码2获取这个线程的Looper。代码3完成Handler初始化。

运行与停止

        完成了初始化操作,IntentService就可以来处理请求了。前面说到IntentService是通过Handler来串行处理请求的,来看看它的源码。

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的源码很简单,我们重写的onHandleIntent方法就是在handleMessage方法里调用的。处理完请求就尝试停止Service。也就是说调用stopSelf方法Service不一定会立刻停止。这里需要结合另外两个方法来解释。

@Override
public void onStart(@Nullable Intent intent, int startId) {
        Message msg = mServiceHandler.obtainMessage();
        //1
        msg.arg1 = startId;
        msg.obj = intent;
        mServiceHandler.sendMessage(msg);
}
    
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
        //2
        onStart(intent, startId);
        return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}

        看到代码1,刚刚stopSelf方法传入的startId就是来自这里。stopSelf方法会判断传入的startId和onStartCommand的startId是否相同。相同就停止服务,不相同就暂时不停止它。
        现在把onStartCommand的startId记为A,把stopSelf传入的startId记为B。A不等于B说明在任务1完成前,任务2请求就来了,如果完成了任务1立即停止服务,任务2的请求就不能得到处理了。同理,A等于B说明任务1完成时还没有新的任务请求发过来,这时立即停止服务并不会有什么不妥,新的任务请求发来了再重新启动服务就可以了,
        如此一来,IntentService就实现了自动停止的功能。接下来再看看服务停止时做了什么。

//IntentService.java
@Override
public void onDestroy() {
       mServiceLooper.quit();
}

//Looper.java
public void quit() {
        mQueue.quit(false);
}

        销毁服务的操作很简单,让Looper停下来就可以了,这里Looper是非安全退出,也就是说,队列里的任务会被取消掉。调用stopSelf(-1)不需要等所有的任务处理完,可以直接停止服务。

请求重传

IntentService有这么一个方法,它可以让Intent实现重传。

/**
     * Sets intent redelivery preferences.  Usually called from the constructor
     * with your preferred semantics.
     *
     * <p>If enabled is true,
     * {@link #onStartCommand(Intent, int, int)} will return
     * {@link Service#START_REDELIVER_INTENT}, so if this process dies before
     * {@link #onHandleIntent(Intent)} returns, the process will be restarted
     * and the intent redelivered.  If multiple Intents have been sent, only
     * the most recent one is guaranteed to be redelivered.
     *
     * <p>If enabled is false (the default),
     * {@link #onStartCommand(Intent, int, int)} will return
     * {@link Service#START_NOT_STICKY}, and if the process dies, the Intent
     * dies along with it.
     */
    public void setIntentRedelivery(boolean enabled) {
        mRedelivery = enabled;
    }

	@Override
	public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
        onStart(intent, startId);
        return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}

        注释里意思是说如果setIntentRedelivery方法传入true,那么在进程被杀死的时候,Intent会被保存下来,等进程重启了再重新发送这个Intent。但是,对于多个Intent只有那个最新的Intent能够重传。其实这是通过onStartCommand方法的返回值来实现的。

参考文章

    https://www.jianshu.com/p/5c1fae2794f6
    https://blog.youkuaiyun.com/mingli198611/article/details/8782772
    https://www.jianshu.com/p/63a644166013

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值