什么是WorkManager

WorkManagerJetpack中的一个库,它扩展了JobScheduler的才能, 提供给应用在后台履行使命的才能。

它能协助应用在满意条件的时分履行后台使命,不论应用进程是否存活。

一般满意如下条件的使命适合运用WorkManager履行:

  • 即便应用被退出,也要确保履行的使命
  • 可推迟的使命
  • 守时履行的使命

WorkManager怎样运用

1. 引入相关库

dependencies {
    def work_version = "2.8.0"
    // (Java only)
    implementation "androidx.work:work-runtime:$work_version"
    // Kotlin + coroutines
    implementation "androidx.work:work-runtime-ktx:$work_version"
    // optional - RxJava2 support
    implementation "androidx.work:work-rxjava2:$work_version"
    // optional - GCMNetworkManager support
    implementation "androidx.work:work-gcm:$work_version"
    // optional - Test helpers
    androidTestImplementation "androidx.work:work-testing:$work_version"
    // optional - Multiprocess support
    implementation "androidx.work:work-multiprocess:$work_version"
}

WorkManager库现在更新到2.8.0版别,读者在运用的时分,能够去WorkManagerAPI参考文档上找到当时的最新版别。

2. 界说一个Worker


public class UploadWorker extends Worker {
   public UploadWorker(@NonNull Context context, @NonNull WorkerParameters params) {
       super(context, params);
   }
   @Override
   public Result doWork() {
     // Do the work here--in this case, upload the images.
     uploadImages();
     // Indicate whether the work finished successfully with the Result
     return Result.success();
   }
}

初始化一个履行使命的UploadWorker,承继自Worker类,在doWork中履行相应的使命。

doWork的返回结果:

  • Result.success(): 作业成功完结
  • Result.failure(): 作业失利
  • Result.retry(): 作业失利,应根据重试战略在其他时间尝试

3. 创立WorkRequest

创立完Worker之后,你需求告诉体系,你的使命想什么时分履行,依照什么战略履行。

1)一次性作业

WorkRequest uploadWorkRequest = new OneTimeWorkRequest.Builder(MyWork.class)
       // Additional configuration
       .build();
  1. 加急作业

2.7.0之后的版别引入了加急作业的概念,履行一些重要的使命能够设置加急处理。

OneTimeWorkRequest request = new OneTimeWorkRequestBuilder<T>()
    .setInputData(inputData)
    .setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
    .build();

加急处理的worker,在Android12之前经过前台服务完结,会在通知栏上显示通知,所以有必要完结getForegroundInfo办法。

不过加急使命并不一定会立刻履行,在某些情况下,可能还是会推迟启动:

  • 体系负载过高:当体系内存等资源不足时
  • 超出加急作业配额约束

3)守时作业

PeriodicWorkRequest saveRequest =
       new PeriodicWorkRequest.Builder(SaveImageToFileWorker.class, 1, TimeUnit.HOURS)
           // Constraints
           .build();

4. 创立约束条件

只有满意约束条件,才会履行使命。假如在履行过程中,不再满意某个约束,WorkManager会停止作业。

Constraints constraints = new Constraints.Builder()
       .setRequiredNetworkType(NetworkType.UNMETERED)
       .setRequiresCharging(true)
       .build();

5. 提交WorkRequest

WorkManager
    .getInstance(myContext)
    .enqueue(uploadWorkRequest);

运用enqueueWorkManager使命提交给体系。

多进程WorkManager

WorkManager 2.6版别开端,支撑多进程的运用场景。能够在一个进程中设置服务,让服务在另一个进程中被调度。

1)设置WorkRequest

           val serviceName = RemoteWorkerService::class.java.name
            val componentName = ComponentName(PACKAGE_NAME, serviceName)
            val oneTimeWorkRequest = buildOneTimeWorkRemoteWorkRequest(
                componentName,
                ExampleRemoteCoroutineWorker::class.java
            )
            workManager?.enqueue(oneTimeWorkRequest)

2)在Manifest中界说RemoteWorkService

        <service
            android:name="androidx.work.multiprocess.RemoteWorkerService"
            android:exported="false"
            android:process=":worker1" />

RemoteWorkerService不需求自己创立,可是需求在Manifest里指定所运转的进程名。

也能够界说自己的Service,需求承继自RemoteWorkService

3)Java承继RemoteListanableWorker

Java:

public class ExampleRemoteListenableWorker extends RemoteListenableWorker {
    private static final String TAG = "ListenableWorker";
    public ExampleRemoteListenableWorker(Context appContext, WorkerParameters workerParams) {
        super(appContext, workerParams);
    }
    @Override
    public ListenableFuture<Result> startRemoteWork() {
        return CallbackToFutureAdapter.getFuture(completer -> {
            Log.i(TAG, "Starting ExampleRemoteListenableWorker");
            // Do some work here.
            return completer.set(Result.success());
        });
    }
}

4) Kotlin承继RemoteCoroutineWorker
Kotlin:

class ExampleRemoteCoroutineWorker(context: Context, parameters: WorkerParameters) :
    RemoteCoroutineWorker(context, parameters) {
    override suspend fun doRemoteWork(): Result {
        Log.d(TAG, "Starting ExampleRemoteCoroutineWorker")
        // Do some work here
        return Result.success()
    }
    companion object {
        private const val TAG = "CoroutineWorker"
    }
}

总结

本篇文章介绍了WorkManager的运用办法,包括如何在多进程中运用WorkManager

WorkManager运用在后台运转的使命,即便App挂掉了,也要确保能完结的使命,或者是一些守时使命。

实质原理也是经过Service的办法拉起进程,履行相应的doWork中的使命。

有一点需求留意,假如从后台拉起进程,由于这个时分App运转在后台,能拿到的资源十分少,很容易就会产生后台ANR。

尽管Service的后台ANR不会弹窗提示用户,可是会影响使命的履行成功率。所以,主张运用多进程的方式,让使命运转到子进程中。

在多进程的情况下,需求在RemoteWorkerService运转的进程中,修正Application中的onCreateattachBaseContext办法,定制属于子进程的初始化逻辑。