IntentService是Service的一个子类,专门用于处理异步请求。它提供了一个默认的工作线程来执行后台操作,旨在简化异步任务处理的复杂性。开发者只需专注于实现onHandleIntent方法来处理后台任务,其余启动和停止Service的底层实现被封装起来。
在实现上,IntentService封装了HandlerService和Handler。在第一次启动时,它的onCreate方法创建了一个HandlerThread,并使用其Looper创建了一个Handler对象mServiceHandler,如下:
@Override
public void onCreate() {
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
每次启动IntentService,都会调用onStartCommand方法,在其内部调用onStart方法,如下:
@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 onStart(@Nullable Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
在ServiceHandler中,通过HandlerThread的Looper顺序处理消息,在handleMessage方法中调用了onHandleIntent方法,并停止了服务:
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);
}
}
onHandleIntent方法是一个抽象方法,它需要我们在子类中实现,它的作用是从intent参数中区分具体的任务,并执行这些任务。
另外,由于每执行一个后台任务就必须启动一次IntentService,而IntentService内部则通过消息的方式向HandlerThread请求执行任务, Handler中的looper是顺序处理消息的,这就意味着IntentService也是顺序执行后台任务的,当有多个后台任务同时存在时,这些后台任务会按照外界发起的顺序排队执行。
下面通过一个示例来进一步说明IntentService的工作方式,如下:
public class LocalIntentService extends IntentService {
private static final String TAG = "LocalIntentService";
public LocalIntentService() {
super(TAG);
}
@Override
protected void onHandleIntent(@Nullable Intent intent) {
if (intent == null) {
return;
}
String action = intent.getStringExtra("task_action");
Log.d(TAG, "onHandleIntent: Received task: action = " + action);
// 模拟耗时操作
SystemClock.sleep(3000);
Log.d(TAG, "onHandleIntent: Completed task: action = " + action);
}
@Override
public void onDestroy() {
Log.d(TAG, "onDestroy: service destroyed.");
super.onDestroy();
}
}
// 发起3个后台任务的请求
Intent service = new Intent(this, LocalIntentService.class);
service.putExtra("task_action", "Task 1");
startService(service);
service.putExtra("task_action", "Task 2");
startService(service);
service.putExtra("task_action", "Task 3");
startService(service);
运行程序后,观察日志:
19:37:00.047 6930-7384 D onHandleIntent: Received task: action = Task 1
19:37:03.049 6930-7384 D onHandleIntent: Completed task: action = Task 1
19:37:03.052 6930-7384 D onHandleIntent: Received task: action = Task 2
19:37:06.053 6930-7384 D onHandleIntent: Completed task: action = Task 2
19:37:06.054 6930-7384 D onHandleIntent: Received task: action = Task 3
19:37:09.056 6930-7384 D onHandleIntent: Completed task: action = Task 3
19:37:09.060 6930-6930 D onDestroy: service destroyed.
从日志中可以看出,三个后台任务是按照它们被启动的顺序依次执行的,并且在所有任务执行完毕后,IntentService才真正停止。
这个示例展示了IntentService顺序执行后台任务的特性,因为它内部使用的HandlerThread的Looper是顺序处理消息的。