一、初始化流程
1、WorkManager集成了androidx.startup 库,通过startup库的ContentProvider在应用启动时进行初始化。
见work-runtime的Manifest文件:
1 2 3 4 5 6 7 8 9
| <provider android:name="androidx.startup.InitializationProvider" android:authorities="${applicationId}.androidx-startup" android:exported="false" tools:node="merge" > <meta-data android:name="androidx.work.WorkManagerInitializer" android:value="androidx.startup" /> </provider>
|
其初始化类为WorkManagerInitializer,其中调用了WorkManager#initialize,然后调用WorkManager的构造函数。
整个流程初始化了如下一些对象:
调度器的创建:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| @NonNull static Scheduler createBestAvailableBackgroundScheduler(@NonNull Context context, @NonNull WorkDatabase workDatabase, Configuration configuration) {
Scheduler scheduler; if (Build.VERSION.SDK_INT >= WorkManagerImpl.MIN_JOB_SCHEDULER_API_LEVEL) { scheduler = new SystemJobScheduler(context, workDatabase, configuration); setComponentEnabled(context, SystemJobService.class, true); Logger.get().debug(TAG, "Created SystemJobScheduler and enabled SystemJobService"); } else { scheduler = tryCreateGcmBasedScheduler(context, configuration.getClock()); if (scheduler == null) { scheduler = new SystemAlarmScheduler(context); setComponentEnabled(context, SystemAlarmService.class, true); Logger.get().debug(TAG, "Created SystemAlarmScheduler"); } } return scheduler; }
|
二、任务
2.1 定义任务
当我们自定义任务时,需要继承Work类,WorkManager内部对Work的结构定义如下:
其中DiagnosticsWorker和CombineContinueationsWorker是内部使用的两个任务。
2.2 提交任务
我们将任务以请求(WorkRequest)的形式提交(enqueue)给WorkManager。WorkManager会将请求装换成内部的WorkContinuation对象。
WorkContinuation可以将多个OneTimeWorkrequest构建成任意依赖关系的无环图。而WorkContinuation的enqueue方法则是任务被执行调度的入口。
2.3 执行任务
对任务进行不同的操作,如:取消、结束、开始等。WorkManager内部会将这些行为转换成对应的Runnable交给调度系统进行执行。
三、任务的调度
提交给WorkManager的任务,会封装成EnqueueRunnable交给默认的SerialExecutor去执行。
EnqueueRunnable的run方法会先将任务加入数据库中保存。然后进行任务调度。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| @Override public void run() { try { if (mWorkContinuation.hasCycles()) { throw new IllegalStateException( String.format("WorkContinuation has cycles (%s)", mWorkContinuation)); } boolean needsScheduling = addToDatabase(); if (needsScheduling) { final Context context = mWorkContinuation.getWorkManagerImpl().getApplicationContext(); PackageManagerHelper.setComponentEnabled(context, RescheduleReceiver.class, true); scheduleWorkInBackground(); } mOperation.setState(Operation.SUCCESS); } catch (Throwable exception) { mOperation.setState(new Operation.State.FAILURE(exception)); } }
|
四、其他
4.1 任务的约束
五、总结
WorkManager库并不算复杂。这种对任务的管理和调度框架的源码,我们可以多看,学习一下里面的设计思路。有个大概的印象,后续写相关逻辑时可以借鉴。
- 借助
startup初始化你的框架
- 构建有依赖关系的任务
- 通过Runnable解耦任务的请求和执行。