Android

关注公众号 jb51net

关闭
首页 > 软件编程 > Android > WorkManager应用退出后台任务

WorkManager解决应用退出后继续运行后台任务

作者:尹学姐

这篇文章主要为大家介绍了WorkManager解决应用退出后继续运行后台任务示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

什么是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的返回结果:

3. 创建WorkRequest

创建完Worker之后,你需要告诉系统,你的任务想什么时候执行,按照什么策略执行。

1)一次性工作

WorkRequest uploadWorkRequest = new OneTimeWorkRequest.Builder(MyWork.class)
       // Additional configuration
       .build();

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方法,定制属于子进程的初始化逻辑。

以上就是WorkManager解决应用退出后继续运行后台任务的详细内容,更多关于WorkManager应用退出后台任务的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文