一拆内、WorkManager簡介
WorkManager是適合用于持久性工作的推薦解決方案顽爹。
持久性的工作:如果工作始終要通過應(yīng)用重啟和系統(tǒng)重新啟動來調(diào)度到逊,便是持久性的工作泉手。
由于大多數(shù)后臺處理操作都是通過持久性工作完成的黔寇,因此 WorkManager 是適用于后臺處理操作的主要推薦 API。
持久性工作的類型:
WorkManager 可處理三種類型的持久性工作:
- 立即執(zhí)行:必須立即開始且很快就完成的任務(wù)斩萌,可以加急缝裤。
- 長時間運行:運行時間可能較長(有可能超過 10 分鐘)的任務(wù)。
-
可延期執(zhí)行:延期開始并且可以定期運行的預(yù)定任務(wù)颊郎。
類型 | 周期 | 使用方式 |
---|---|---|
立即 | 一次性 | OneTimeWorkRequest 和 Worker憋飞。如需處理加急工作,請對 OneTimeWorkRequest 調(diào)用 setExpedited()姆吭。 |
長期運行 | 一次性或定期 | 任意 WorkRequest 或 Worker榛做。在工作器中調(diào)用 setForeground() 來處理通知。 |
可延期 | 一次性或定期 | PeriodicWorkRequest 和 Worker内狸。 |
WorkManager 適用于:
- 主要用用于后臺運行的操作检眯;
- 用于延遲運行并且再應(yīng)用退出或設(shè)備重啟必須能夠可靠運行的任務(wù)。
Android為后臺任務(wù)提供了多種解決方案答倡,如JobScheduler轰传,Loader驴党,Service等瘪撇。如果這些API沒有被適當?shù)厥褂茫赡軙拇罅康碾娏俊?/p>
Service也是用于后臺運行港庄,為什么不用Service倔既?
原因:Google自O(shè)reo(API 26) 開始,對后臺service服務(wù)做了一些個限制鹏氧,如在不被允許創(chuàng)建后臺服務(wù)的情況下渤涌,調(diào)用了startService()方法,會導(dǎo)致IllegalStateException異常把还。因此如果要繼續(xù)使用service就必須通過Context類得靜態(tài)方法startForegroundService()來啟動前臺服務(wù)实蓬,系統(tǒng)也創(chuàng)建了服務(wù),這就導(dǎo)致了應(yīng)用得在5秒鐘之內(nèi)調(diào)用該服務(wù)的 startForeground() 方法使其位于前臺被用戶發(fā)現(xiàn)吊履,要是超過了5s那App就拋ANR(Application Not Response)安皱。
1、WorkManager兼容性
WorkManager最低能兼容API Level 14艇炎,幾乎兼容100%Android設(shè)備酌伊。
WorkManager能依據(jù)設(shè)備的情況,選擇不同的執(zhí)行方案缀踪。在API Level 23+居砖,通過JobScheduler來完成任務(wù)虹脯,而在API Level 23以下的設(shè)備中,通過AlarmManager和Broadcast Receivers組合完成任務(wù)奏候。但無論采用哪種方案循集,任務(wù)最終都是交由Executor來完成。
2蔗草、WorkManager特點
1.針對不需要及時完成的任務(wù)
比如暇榴,發(fā)送應(yīng)用程序日志,同步應(yīng)用程序數(shù)據(jù)蕉世,備份用戶數(shù)據(jù)等蔼紧。站在業(yè)務(wù)的角度,這些任務(wù)都不需要立即完成狠轻,如果我們自己來管理這些任務(wù)奸例,邏輯可能會非常復(fù)雜,若API使用不恰當向楼,可能會消耗大量電量查吊。
2.保證任務(wù)一定會被執(zhí)行
WorkManager能保證任務(wù)一定會被執(zhí)行,即使你的應(yīng)用程序當前不在運行中湖蜕,哪怕你的設(shè)備重啟逻卖,任務(wù)仍然會在適當?shù)臅r候被執(zhí)行。這是因為WorkManager有自己的數(shù)據(jù)庫昭抒,關(guān)于任務(wù)的所有信息和數(shù)據(jù)都保存在這個數(shù)據(jù)庫中评也,因此,只要你的任務(wù)交給了WorkManager灭返,哪怕你的應(yīng)用程序徹底退出盗迟,或者設(shè)備重新啟動,WorkManager依然能夠保證完成你交給的任務(wù)熙含。
注意:WorkManager不是一種新的工作線程罚缕,它的出現(xiàn)不是為了替代其它類型的工作線程。工作線程通常立即運行怎静,并在執(zhí)行完成后給到用戶反饋邮弹。而WorkManager不是即時的,它不能保證任務(wù)能立即得到執(zhí)行蚓聘。
二腌乡、WorkManager使用
1、首先三個重要的類
- Worker
我們要執(zhí)行的具體任務(wù)或粮。需要繼承Worker,重寫doWork方法导饲,然后在里面寫具體的邏輯。 - WorkRequest
上面的Worker是定義了我們要在后臺的任務(wù),而這個類是對Worker的包裝渣锦。
下面兩個都是繼承了WorkRequest:
OneTimeWorkRequest: 只執(zhí)行一次的任務(wù)
PeriodicWorkRequest: 重復(fù)執(zhí)行的任務(wù)(重復(fù)間隔大于15分鐘) - WorkManager
是對WorkRequest的管理類硝岗。
2、在app的build.gradle中添加依賴
dependencies {
def work_version = "2.7.1"
// (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"
}
3袋毙、創(chuàng)建自定義Worker任務(wù)
class MyWorker extends Worker {
private WorkerParameters workerParameters;
public MyWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
workerParameters = workerParams;
}
@NonNull
@Override
public Result doWork() {
Log.e("MyWorker", "doWork()");
//從外面?zhèn)鬟M來的值
String value = workerParameters.getInputData().getString("key");
//處理數(shù)據(jù)后創(chuàng)建data
Data data = new Data.Builder().putString("key", value).build();
return Result.success(data);
}
}
doWork()方法有三種類型的返回值:
- 執(zhí)行成功返回Result.success()型檀,可攜帶參數(shù)
- 執(zhí)行失敗返回Result.failure(),可攜帶參數(shù)
- 需要重新執(zhí)行返回Result.retry()
4听盖、使用WorkRequest配置任務(wù)并把請求添加到請求隊列
通過WorkRequest配置我們的任務(wù)何時運行以及如何運行胀溺。
//1、創(chuàng)建傳遞給Work的參數(shù)
Data sendData = new Data.Builder().putString("key", "來自Activity的數(shù)據(jù)").build();
//2皆看、初始化請求對象request仓坞,并添加自定義Worker
OneTimeWorkRequest oneTimeWorkRequest = new OneTimeWorkRequest.Builder(MyWorker.class).setInputData(sendData).build();
//3、添加回調(diào)更新
WorkManager.getInstance(activity).getWorkInfoByIdLiveData(oneTimeWorkRequest.getId()).observe(activity, new Observer<WorkInfo>() {
@Override
public void onChanged(WorkInfo workInfo) {
//注意這個方法會回調(diào)多次腰吟,要加這個判斷
if(workInfo.getState().isFinished()){
//執(zhí)行完成的處理无埃,接受worker返回的結(jié)果
//這里的key與MyWorker的key需要一致
String result = workInfo.getOutputData().getString("key");
}
}
});
//4、添加到任務(wù)隊列
WorkManager.getInstance(activity).enqueue(oneTimeWorkRequest);
注意:Data只能用于傳遞一些小的基本類型數(shù)據(jù)毛雇,且數(shù)據(jù)最大不能超過10kb嫉称。
三、WorkManager其他使用方式
1灵疮、WorkRequest兩個子類
- OneTimeWorkRequest:執(zhí)行一次性任務(wù)
- PeriodicWorkRequest:執(zhí)行周期性任務(wù)
2织阅、WorkRequest可設(shè)置任務(wù)觸發(fā)條件
以下皆使用OneTimeWorkRequest,OneTimeWorkRequest和PeriodicWorkRequest使用方式相同震捣。
//1荔棉、創(chuàng)建條件:在設(shè)備處于充電,網(wǎng)絡(luò)已連接伍派,且電池電量充足的狀態(tài)下江耀,才觸發(fā)我們設(shè)置的任務(wù)剩胁。
Constraints constraints = new Constraints.Builder()
//在設(shè)備處于充電
.setRequiresCharging(true)
//網(wǎng)絡(luò)已連接
.setRequiredNetworkType(NetworkType.CONNECTED)
//電池電量充足的狀態(tài)下
.setRequiresBatteryNotLow(true)
//充電中
.setRequiresCharging(true)
//cpu空閑時
.setRequiresDeviceIdle(true)
//可用存儲是否不低于最小值
.setRequiresStorageNotLow(true)
.build();
//2诉植、設(shè)置條件
OneTimeWorkRequest oneTimeWorkRequest = new OneTimeWorkRequest.Builder(MyWorker.class)
.setInputData(sendData)
.setConstraints(constraints)
.build();
3、設(shè)置延遲執(zhí)行任務(wù)
假設(shè)你沒有設(shè)置觸發(fā)條件昵观,或者當你設(shè)置的觸發(fā)條件符合系統(tǒng)的執(zhí)行要求晾腔,此時,系統(tǒng)有可能立刻執(zhí)行該任務(wù)啊犬,但如果你希望能夠延遲執(zhí)行灼擂,那么可以通過setInitialDelay()方法,延后任務(wù)的執(zhí)行觉至。
OneTimeWorkRequest oneTimeWorkRequest = new OneTimeWorkRequest.Builder(MyWorker.class)
//設(shè)置傳入Worker數(shù)據(jù)
.setInputData(sendData)
//設(shè)置觸發(fā)條件
.setConstraints(constraints)
//設(shè)置符合觸發(fā)條件后剔应,延遲10秒執(zhí)行
.setInitialDelay(10, TimeUnit.SECONDS)
//設(shè)置指數(shù)退避策略
.setBackoffCriteria(BackoffPolicy.LINEAR, OneTimeWorkRequest.MIN_BACKOFF_MILLIS, TimeUnit.MILLISECONDS)//設(shè)置指數(shù)退避算法
//設(shè)置標簽
.addTag("UploadTag")
.build();
4、設(shè)置指數(shù)退避策略
假如Worker線程的執(zhí)行出現(xiàn)了異常,比如服務(wù)器宕機峻贮,那么你可能希望過一段時間席怪,重試該任務(wù)。那么你可以在Worker的doWork()方法中返回Result.retry()纤控,系統(tǒng)會有默認的指數(shù)退避策略來幫你重試任務(wù)挂捻,你也可以通過setBackoffCriteria()方法,自定義指數(shù)退避策略船万。
OneTimeWorkRequest oneTimeWorkRequest = new OneTimeWorkRequest.Builder(MyWorker.class)
//設(shè)置傳入Worker數(shù)據(jù)
.setInputData(sendData)
//設(shè)置觸發(fā)條件
.setConstraints(constraints)
//設(shè)置符合觸發(fā)條件后刻撒,延遲10秒執(zhí)行
.setInitialDelay(10, TimeUnit.SECONDS)
//設(shè)置指數(shù)退避策略
.setBackoffCriteria(BackoffPolicy.LINEAR, OneTimeWorkRequest.MIN_BACKOFF_MILLIS, TimeUnit.MILLISECONDS)//設(shè)置指數(shù)退避算法
//設(shè)置標簽
.addTag("UploadTag")
.build();
5、為任務(wù)設(shè)置Tag標簽
設(shè)置Tag后耿导,你就可以通過該抱歉跟蹤任務(wù)的狀態(tài)WorkManager.getWorkInfosByTagLiveData(String tag)或者取消任務(wù)WorkManager.cancelAllWorkByTag(String tag)声怔。
OneTimeWorkRequest oneTimeWorkRequest = new OneTimeWorkRequest.Builder(MyWorker.class)
//設(shè)置傳入Worker數(shù)據(jù)
.setInputData(sendData)
//設(shè)置觸發(fā)條件
.setConstraints(constraints)
//設(shè)置符合觸發(fā)條件后,延遲10秒執(zhí)行
.setInitialDelay(10, TimeUnit.SECONDS)
//設(shè)置指數(shù)退避策略
.setBackoffCriteria(BackoffPolicy.LINEAR, OneTimeWorkRequest.MIN_BACKOFF_MILLIS, TimeUnit.MILLISECONDS)//設(shè)置指數(shù)退避算法
//設(shè)置標簽
.addTag("UploadTag")
.build();
6舱呻、將任務(wù)提交給系統(tǒng)捧搞。
WorkManager.enqueue()方法會將你配置好的WorkRequest交給系統(tǒng)來執(zhí)行。
WorkManager.getInstance(activity).enqueue(oneTimeWorkRequest);
7狮荔、觀察任務(wù)的狀態(tài)
任務(wù)在提交給系統(tǒng)后胎撇,通過WorkInfo獲知任務(wù)的狀態(tài),WorkInfo包含了任務(wù)的id殖氏,tag晚树,以及Worker對象傳遞過來的outputData,以及任務(wù)當前的狀態(tài)雅采。有三種方式可以得到WorkInfo對象爵憎。
WorkManager.getWorkInfosByTag()
WorkManager.getWorkInfoById()
WorkManager.getWorkInfosForUniqueWork()
如果你希望能夠?qū)崟r獲知任務(wù)的狀態(tài)。這三個方法還有對應(yīng)的LiveData方法婚瓜。
WorkManager.getWorkInfosByTagLiveData()
WorkManager.getWorkInfoByIdLiveData()
WorkManager.getWorkInfosForUniqueWorkLiveData()
通過觀察LiveData宝鼓,我們便可以在任務(wù)狀態(tài)發(fā)生變化的時候,收到通知巴刻。
WorkManager.getInstance(activity).getWorkInfoByIdLiveData(oneTimeWorkRequest.getId()).observe(activity, new Observer<WorkInfo>() {
@Override
public void onChanged(WorkInfo workInfo) {
//注意這個方法會回調(diào)多次愚铡,要加這個判斷
if(workInfo.getState().isFinished()){
//執(zhí)行完成的處理,接受worker返回的結(jié)果
//這里的key與MyWorker的key需要一致
String result = workInfo.getOutputData().getString("key");
}
}
});
8胡陪、取消任務(wù)
與觀察任務(wù)類似的沥寥,我們也可以根據(jù)Id或者Tag取消某個任務(wù),或者取消所有任務(wù)柠座。
WorkManager.getInstance(activity).cancelWorkById(UUID)
WorkManager.getInstance(activity).cancelAllWorkByTag("")
WorkManager.getInstance(activity).cancelAllWork();
9邑雅、周期任務(wù)PeriodicWorkRequest
一次性任務(wù),即任務(wù)在成功完成后妈经,便徹底結(jié)束淮野。而周期性任務(wù)則會按照設(shè)定的時間定期執(zhí)行捧书。
注意:周期性任務(wù)的間隔時間不能小于15分鐘。源碼設(shè)置最小15分鐘骤星。
PeriodicWorkRequest workRequest = new PeriodicWorkRequest.Builder(MyWorker.class, 15, TimeUnit.MINUTES)
.setConstraints(constraints)
.build();
10鳄厌、任務(wù)鏈
如果你有一系列的任務(wù)需要順序執(zhí)行,那么可以利用WorkManager.beginWith().then().then().enqueue()方法;
例如:我們在上傳圖片之前妈踊,需要先對圖片進行壓縮了嚎,還需要更新本地圖片。壓縮與更新本地圖片二者沒有順序廊营,但與上傳圖片存在先后順序歪泳。
WorkManager.getInstance(this).beginWith(compressWorkRequest, updateLocalWorkRequest).then(uploadWorkRequest).enqueue();
11、WorkContinuation復(fù)雜任務(wù)鏈
執(zhí)行順序:
任務(wù)鏈一:A—>B
任務(wù)鏈二:C—>D
任務(wù)鏈一—>任務(wù)鏈二—>E
WorkContinuation workContinuation1 = WorkManager.getInstance(activity).beginWith(WorkRequestA).then(WorkRequestB);
WorkContinuation workContinuation2 = WorkManager.getInstance(activity).beginWith(WorkRequestC).then(WorkRequestD);
List<WorkContinuation> taskList = new ArrayList<>();
taskList.add(workContinuation1);
taskList.add(workContinuation2);
WorkContinuation.combine(taskList).then(WorkRequestE).enqueue();
四露筒、Kotlin中使用
1呐伞、CoroutineWorker 中的線程處理
對于 Kotlin 用戶,WorkManager 為協(xié)程提供了一流的支持慎式。如要開始使用伶氢,請將 work-runtime-ktx
包含到您的 gradle 文件中。不要擴展 Worker
瘪吏,而應(yīng)擴展 CoroutineWorker
癣防,后者包含 doWork()
的掛起版本。例如掌眠,如果要構(gòu)建一個簡單的 CoroutineWorker
來執(zhí)行某些網(wǎng)絡(luò)操作蕾盯,您需要執(zhí)行以下操作:
class CoroutineDownloadWorker(
context: Context,
params: WorkerParameters
) : CoroutineWorker(context, params) {
override suspend fun doWork(): Result {
val data = downloadSynchronously("https://www.google.com")
saveData(data)
return Result.success()
}
}
請注意,CoroutineWorker.doWork()
是一個“掛起”函數(shù)蓝丙。此代碼不同于 Worker
级遭,不會在 Configuration
中指定的 Executor
中運行,而是默認為 Dispatchers.Default
渺尘。您可以提供自己的 CoroutineContext
來自定義這個行為挫鸽。在上面的示例中,您可能希望在 Dispatchers.IO
上完成此操作鸥跟,如下所示:
class CoroutineDownloadWorker(
context: Context,
params: WorkerParameters
) : CoroutineWorker(context, params) {
override suspend fun doWork(): Result {
withContext(Dispatchers.IO) {
val data = downloadSynchronously("https://www.google.com")
saveData(data)
return Result.success()
}
}
}
CoroutineWorker
通過取消協(xié)程并傳播取消信號來自動處理停工情況丢郊。您無需執(zhí)行任何特殊操作來處理停工情況。
2锌雀、在其他進程中運行 CoroutineWorker
您還可以使用 RemoteCoroutineWorker
(ListenableWorker
的實現(xiàn))將工作器綁定到特定進程蚂夕。
RemoteCoroutineWorker
會使用您在構(gòu)建工作請求時于輸入數(shù)據(jù)中提供的兩個額外參數(shù)綁定到特定進程:ARGUMENT_CLASS_NAME
和 ARGUMENT_PACKAGE_NAME
。
以下示例演示了如何構(gòu)建綁定到特定進程的工作請求:
val PACKAGE_NAME = "com.example.background.multiprocess"
val serviceName = RemoteWorkerService::class.java.name
val componentName = ComponentName(PACKAGE_NAME, serviceName)
val data: Data = Data.Builder()
.putString(ARGUMENT_PACKAGE_NAME, componentName.packageName)
.putString(ARGUMENT_CLASS_NAME, componentName.className)
.build()
return OneTimeWorkRequest.Builder(ExampleRemoteCoroutineWorker::class.java)
.setInputData(data)
.build()
對于每個 RemoteWorkerService腋逆,您還需要在 AndroidManifest.xml 文件中添加服務(wù)定義:
<manifest ... >
<service
android:name="androidx.work.multiprocess.RemoteWorkerService"
android:exported="false"
android:process=":worker1" />
<service
android:name=".RemoteWorkerService2"
android:exported="false"
android:process=":worker2" />
...
</manifest>
3、RxWorker 中的線程處理
我們在 WorkManager 與 RxJava 之間提供互操作性侈贷。如需開始使用這種互操作性惩歉,除了在您的 gradle 文件中包含 work-runtime
之外等脂,還應(yīng)包含 work-rxjava3
依賴項。而且還有一個支持 rxjava2 的 work-rxjava2
依賴項撑蚌,您可以根據(jù)情況使用上遥。
然后,您應(yīng)該擴展 RxWorker
争涌,而不是擴展 Worker
粉楚。最后替換 RxWorker.createWork()
方法以返回 Single<Result>
,用于表示代碼執(zhí)行的 Result
亮垫,如下所示:
class RxDownloadWorker(
context: Context,
params: WorkerParameters
) : RxWorker(context, params) {
override fun createWork(): Single<Result> {
return Observable.range(0, 100)
.flatMap { download("https://www.example.com") }
.toList()
.map { Result.success() }
}
}
請注意模软,RxWorker.createWork()
在主線程上調(diào)用,但默認情況下會在后臺線程上訂閱返回值饮潦。您可以替換 RxWorker.getBackgroundScheduler()
來更改訂閱線程燃异。
當 RxWorker
為 onStopped()
時,系統(tǒng)會處理訂閱继蜡,因此您無需以任何特殊方式處理停工情況回俐。
4、ListenableWorker 中的線程處理
在某些情況下稀并,您可能需要提供自定義線程處理策略仅颇。例如,您可能需要處理基于回調(diào)的異步操作碘举。在這種情況下灵莲,不能只依靠 Worker
來完成操作,因為它無法以阻塞方式完成這項工作殴俱。WorkManager 通過 ListenableWorker
支持該用例政冻。ListenableWorker
是最基本的工作器 API;Worker
线欲、CoroutineWorker
和 RxWorker
都是從這個類衍生而來的明场。ListenableWorker
只會發(fā)出信號以表明應(yīng)該開始和停止工作,而線程處理則完全交您決定李丰。開始工作信號在主線程上調(diào)用苦锨,因此請務(wù)必手動轉(zhuǎn)到您選擇的后臺線程。
抽象方法 ListenableWorker.startWork()
會返回一個將使用操作的 Result
設(shè)置的 ListenableFuture
趴泌。ListenableFuture
是一個輕量級接口:它是一個 Future
舟舒,用于提供附加監(jiān)聽器和傳播異常的功能。在 startWork
方法中嗜憔,應(yīng)該返回 ListenableFuture
秃励,完成操作后,您需要使用操作的 Result
設(shè)置這個返回結(jié)果吉捶。您可以通過以下兩種方式之一創(chuàng)建 ListenableFuture
實例:
- 如果您使用的是 Guava夺鲜,請使用
ListeningExecutorService
皆尔。 - 否則,請將
councurrent-futures
包含到您的 gradle 文件中并使用CallbackToFutureAdapter
币励。
如果您希望基于異步回調(diào)執(zhí)行某些工作慷蠕,則應(yīng)以類似如下的方式執(zhí)行:
class CallbackWorker(
context: Context,
params: WorkerParameters
) : ListenableWorker(context, params) {
override fun startWork(): ListenableFuture<Result> {
return CallbackToFutureAdapter.getFuture { completer ->
val callback = object : Callback {
var successes = 0
override fun onFailure(call: Call, e: IOException) {
completer.setException(e)
}
override fun onResponse(call: Call, response: Response) {
successes++
if (successes == 100) {
completer.set(Result.success())
}
}
}
repeat(100) {
downloadAsynchronously("https://example.com", callback)
}
callback
}
}
}
如果您的工作停止會發(fā)生什么?如果預(yù)計工作會停止食呻,則始終會取消 ListenableWorker
的 ListenableFuture
流炕。通過使用 CallbackToFutureAdapter
,您只需添加一個取消監(jiān)聽器即可仅胞,如下所示:
class CallbackWorker(
context: Context,
params: WorkerParameters
) : ListenableWorker(context, params) {
override fun startWork(): ListenableFuture<Result> {
return CallbackToFutureAdapter.getFuture { completer ->
val callback = object : Callback {
var successes = 0
override fun onFailure(call: Call, e: IOException) {
completer.setException(e)
}
override fun onResponse(call: Call, response: Response) {
++successes
if (successes == 100) {
completer.set(Result.success())
}
}
}
completer.addCancellationListener(cancelDownloadsRunnable, executor)
repeat(100) {
downloadAsynchronously("https://example.com", callback)
}
callback
}
}
}
在其他進程中運行 ListenableWorker
您還可以使用 RemoteListenableWorker
(ListenableWorker
的實現(xiàn))將工作器綁定到特定進程每辟。
RemoteListenableWorker
會使用您在構(gòu)建工作請求時于輸入數(shù)據(jù)中提供的兩個額外參數(shù)綁定到特定進程:ARGUMENT_CLASS_NAME
和 ARGUMENT_PACKAGE_NAME
。
以下示例演示了如何構(gòu)建綁定到特定進程的工作請求:
val PACKAGE_NAME = "com.example.background.multiprocess"
val serviceName = RemoteWorkerService::class.java.name
val componentName = ComponentName(PACKAGE_NAME, serviceName)
val data: Data = Data.Builder()
.putString(ARGUMENT_PACKAGE_NAME, componentName.packageName)
.putString(ARGUMENT_CLASS_NAME, componentName.className)
.build()
return OneTimeWorkRequest.Builder(ExampleRemoteListenableWorker::class.java)
.setInputData(data)
.build()
對于每個 RemoteWorkerService饼问,您還需要在 AndroidManifest.xml 文件中添加服務(wù)定義:
<manifest ... >
<service
android:name="androidx.work.multiprocess.RemoteWorkerService"
android:exported="false"
android:process=":worker1" />
<service
android:name=".RemoteWorkerService2"
android:exported="false"
android:process=":worker2" />
...
</manifest>
五影兽、總結(jié)
1、WorkManager作用處理后臺任務(wù)莱革。出于設(shè)備電量的考慮峻堰,為開發(fā)者提供了WorkManager,旨在將一些不需要及時完成的任務(wù)交給它來完成盅视。
2捐名、WorkManager會根據(jù)系統(tǒng)的版本,使用不同的策略來完成任務(wù)闹击,有可能因為版本原因無法正常使用镶蹋。
3、周期任務(wù):Android認為Success和Failure都屬于終止類的通知赏半,可能使用LiveData觀察周期任務(wù)時不會收到Success這類的通知贺归。