WorkManager基本使用及源码分析(四) - SystemJobService

2021年02月06日 99 字 Jetpack


目录


源码篇

上一篇中我们简单使用了WorkManager的一般功能,基础使用还是比较简单的。“WorkManager 是一个 API,可供您轻松调度那些即使在退出应用或重启设备后仍应运行的可延期异步任务”。那么我们来了解一下他到底是怎么工作的吧。

SystemJobService

Service invoked by {@link android.app.job.JobScheduler} to run work tasks.

服务将被JobScheduler调用来执行工作任务。
从描述可得SystemJobServiceSystemAlarmService职责是一致的,都是“run work tasks”。

类似地,我们可以猜测SystemJobService执行流程始于onStartJob终于onStopJob

SystemJobService.onCreate()获取了WorkManagerImpl实例并将执行监听绑定到(任务)处理器Processor:

1
2
3
4
5
6
// 还记得WorkManagerImpl是哪里初始化的吗?
mWorkManagerImpl = WorkManagerImpl.getInstance(getApplicationContext());
// 记住此处addExecutionListener
// 记住此处addExecutionListener
// 记住此处addExecutionListener
mWorkManagerImpl.getProcessor().addExecutionListener(this);

当SystemJobService被调用时会执行SystemJobService.onStartJob(),此时会将JobParameters以workId为Key存入工作Map中,并初始化WorkerParameters.RuntimeExtras, 最终调用mWorkManagerImpl.startWork(workSpecId, runtimeExtras)执行任务:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public boolean onStartJob(@NonNull JobParameters params) {
// WorkManagerImpl NonNull
String workSpecId = getWorkSpecIdFromJobParameters(params);
// workSpecId NonNull
// 保证mJobParameters 工作参数集只进或只出
synchronized (mJobParameters) {
if (mJobParameters.containsKey(workSpecId)) {
// log
return false;
}
// 存入工作参数
mJobParameters.put(workSpecId, params);
}
// 初始化WorkerParameters.RuntimeExtras

// WorkManagerImpl执行任务
mWorkManagerImpl.startWork(workSpecId, runtimeExtras);
}

WorkManagerImpl.startWork后续会执行 mWorkManagerImpl.getProcessor().startWork(mWorkSpecId, mRuntimeExtras)

由于内容流程较长且属于公共流程,关于Processor.startWork()将单独整理未一小节,点击此处查看

Processor.startWork()中代码可知,流程末尾onExecuted中遍历执行的executionListener.onExecuted(workSpecId, needsReschedule)会调用SystemJobService.onExecuted():

1
2
3
4
5
6
7
8
9
10
11
@Override
public void onExecuted(@NonNull String workSpecId, boolean needsReschedule) {
Logger.get().debug(TAG, String.format("%s executed on JobScheduler", workSpecId));
JobParameters parameters;
synchronized (mJobParameters) {
parameters = mJobParameters.remove(workSpecId);
}
if (parameters != null) {
jobFinished(parameters, needsReschedule);
}
}

当然,根据JobService的生命周期,我们可以认定,最后会调用SystemJobService.onStopJob()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Override
public boolean onStopJob(@NonNull JobParameters params) {
if (mWorkManagerImpl == null) {
return true;
}

String workSpecId = getWorkSpecIdFromJobParameters(params);
if (TextUtils.isEmpty(workSpecId)) {
return false;
}

// mJobParameters数据安全
synchronized (mJobParameters) {
// 移出任务参数队列(Map)
mJobParameters.remove(workSpecId);
}
// 结束此任务
mWorkManagerImpl.stopWork(workSpecId);
return !mWorkManagerImpl.getProcessor().isCancelled(workSpecId);
}

至此,从JobService调用SystemJobService执行任务到最终任务结束流程形成了一个完整的链。