WorkManager解决应用退出后继续运行后台任务
作者:尹学姐
什么是WorkManager
WorkManager
是Jetpack
中的一个库,它扩展了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();
- 加急工作
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);
使用enqueue
将WorkManager
任务提交给系统。
多进程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
中的onCreate
和attachBaseContext
方法,定制属于子进程的初始化逻辑。
以上就是WorkManager解决应用退出后继续运行后台任务的详细内容,更多关于WorkManager应用退出后台任务的资料请关注脚本之家其它相关文章!