IntentService源码分析

  1. IntentService 如何单独开启一个新的工作线程?
  2. IntentService如何通过 onStartCommand() 传递给服务 intent 被依次插入到工作
    队列中?
问题 1 IntentService 如何单独开启一个新的工作线程
@Override
public void onCreate() {
        // HandlerThread继承自Thread,内部封装了Looper 
        //通过实例化HandlerThread新建线程并启动 
        //所以使用IntentService时不需要额外新建线程

        super.onCreate();
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
        thread.start();

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

private final class ServiceHandler extends Handler {
        public ServiceHandler(Looper looper) {
            super(looper);
        }

// IntentService的handleMessage方法把接收的消息交给onHandleIntent()处理
// onHandleIntent()是一个抽象方法,使用时需要重写的方法
        @Override
        public void handleMessage(Message msg) {

// onHandleIntent 方法在工作线程中执行,执行完调用 stopSelf() 结束服务。
            onHandleIntent((Intent)msg.obj);

//onHandleIntent 处理完成后 IntentService会调用 stopSelf() 自动停止。
            stopSelf(msg.arg1);
        }
}

// onHandleIntent()是一个抽象方法,使用时需要重写的方法
@WorkerThread 
protected abstract void onHandleIntent(Intent intent);
问题 2 IntentService 如何通过 onStartCommand() 传递给服务 intent 被依次插入
到工作队列中?
@Override
    public void onStart(@Nullable Intent intent, int startId) {
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
//把 intent 参数包装到 message 的 obj 中,然后发送消息,即添加到消 息队列里
//这里的Intent 就是启动服务时startService(Intent) 里的 Intent。
        msg.obj = intent;
        mServiceHandler.sendMessage(msg);
    }

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

//清除消息队列中的消息
    @Override
    public void onDestroy() {
        mServiceLooper.quit();
    }

总结:

从上面源码可以看出, IntentService 本质是采用 Handler & HandlerThread 方式:
1. 通过 HandlerThread 单独开启一个名为 IntentService 的线程
2. 创建一个名叫 ServiceHandler 的内部 Handler
3. 把内部 Handler HandlerThread 所对应的子线程进行绑定
4. 通过 onStartCommand() 传递给服务 intent ,依次插入到工作队列中,并逐个发送给onHandleIntent()
5. 通过 onHandleIntent() 来依次处理所有 Intent 请求对象所对应的任务因此我们通过复写方法onHandleIntent() ,再在里面根据 Intent 的不同进行不同的线程操作就可以了
 
注意事项:工作任务队列是顺序执行的。
如果一个任务正在 IntentService 中执行,此时你再发送一个新的任务请求,这个新的任务会一直等待直到前面一个任务执行完毕才开始执行。
 
原因:
1. 由于 onCreate() 方法只会调用一次,所以只会创建一个工作线程;
2. 当多次调用 startService(Intent) 时( onStartCommand 也会调用多次)其实并不会创建新的工作线程,只是把消息加入消息队列中等待执行,所以,多次启动 IntentService 会按顺序执行事件;
3. 如果服务停止,会清除消息队列中的消息,后续的事件得不到执行。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值