IntentService工作流程

44 阅读3分钟

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是顺序处理消息的。