IntentService 源码阅读

687 阅读2分钟

看IntentService 源码头部注释

  1. IntentService 是用来处理异步请求,服务按需开启,按序使用一个工作线程,并在工作完结束
  2. 使用时,只需继承 IntentService 并实现 onHandleIntent 方法,使用 Android Studio 右键方式创建,提供一个极好的范式。
  3. 每个请求都在单个工作线程里执行

IntentService 使用范式

我们 右键-> New -> Service -> Service(Intent Service) 可以创建一个即开即用的 IntentService 范式。


class MyIntentService : IntentService("MyIntentService") {
 companion object {
        //[1] 外界调用方式,连 startService 都省略了,直接传参数
        @JvmStatic
        fun startActionFoo(context: Context, param1: String, param2: String) {
            val intent = Intent(context, MyIntentService::class.java).apply {
                action = ACTION_FOO
                putExtra(EXTRA_PARAM1, param1)
                putExtra(EXTRA_PARAM2, param2)
            }
            context.startService(intent)
        }
    }
    
    //[2] onHandleIntent 做分发台
    override fun onHandleIntent(intent: Intent?) {
        when (intent?.action) {
            ACTION_FOO -> {
                val param1 = intent.getStringExtra(EXTRA_PARAM1)
                val param2 = intent.getStringExtra(EXTRA_PARAM2)
                handleActionFoo(param1, param2)
            }
            ACTION_BAZ -> {
               ..
            }
        }
    }
    
    //[3] 填业务
    private fun handleActionFoo(param1: String, param2: String) {
        TODO("Handle action Foo")
    }
}

那我们原先的 service 是怎么样的呢,请看下面代码:

class MyService : Service() {

    override fun onBind(intent: Intent): IBinder {
        TODO("Return the communication channel to the service.")
    }
}

小结:

  1. 可以看到 Service 就提供一个 onBind 方法,其他一切都得自己搞
  2. IntentService 官方提供一个扩展性极高的范式,推荐使用 IntentService

源码解析

那么既然推荐我们 IntentService ,接下来看看里面还有没有什么宝藏可以挖。于是我默默点开了 IntentService 的源码。

源码还是简单易懂的。

// IntentService.java

// [1] 继承 Handler 的 ServiceHandler, handleMessage 调用上面的消息分发台 onHandleIntent 抽象方法,执行完后调用 stopSelf 暂停自身
// [2] 使用 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);
        }
}

@Override
    public void onCreate() {
        super.onCreate();
        //[3] 业务操作在该线程里,复用同一线程
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
        thread.start();

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

    @Override
    public void onStart(@Nullable Intent intent, int startId) {
        Message msg = mServiceHandler.obtainMessage();
        //[4] startId 用来关闭自身
        msg.arg1 = startId;
        msg.obj = intent;
        mServiceHandler.sendMessage(msg);
    }

小结:

  1. IntentService 内部使用 Handler 做消息转发,作为其扩展性的基础
  2. 业务执行在新起的工作线程里,同时起的多个任务能够相同线程执行