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