看IntentService 源码头部注释
- IntentService 是用来处理异步请求,服务按需开启,按序使用一个工作线程,并在工作完结束
- 使用时,只需继承 IntentService 并实现 onHandleIntent 方法,使用 Android Studio 右键方式创建,提供一个极好的范式。
- 每个请求都在单个工作线程里执行
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.")
}
}
小结:
- 可以看到 Service 就提供一个 onBind 方法,其他一切都得自己搞
- 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);
}
小结:
- IntentService 内部使用 Handler 做消息转发,作为其扩展性的基础
- 业务执行在新起的工作线程里,同时起的多个任务能够相同线程执行