WorkManager解決應(yīng)用退出后繼續(xù)運行后臺任務(wù)
什么是WorkManager
WorkManager
是Jetpack
中的一個庫,它擴展了JobScheduler
的能力, 提供給應(yīng)用在后臺執(zhí)行任務(wù)的能力。
它能幫助應(yīng)用在滿足條件的時候執(zhí)行后臺任務(wù),不管應(yīng)用進程是否存活。
一般滿足如下條件的任務(wù)適合使用WorkManager
執(zhí)行:
- 即使應(yīng)用被退出,也要保證執(zhí)行的任務(wù)
- 可推遲的任務(wù)
- 定期執(zhí)行的任務(wù)
WorkManager怎么使用
1. 引入相關(guān)庫
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(); } }
初始化一個執(zhí)行任務(wù)的UploadWorker
,繼承自Worker
類,在doWork
中執(zhí)行相應(yīng)的任務(wù)。
doWork
的返回結(jié)果:
Result.success()
: 工作成功完成Result.failure()
: 工作失敗Result.retry()
: 工作失敗,應(yīng)根據(jù)重試策略在其他時間嘗試
3. 創(chuàng)建WorkRequest
創(chuàng)建完Worker
之后,你需要告訴系統(tǒng),你的任務(wù)想什么時候執(zhí)行,按照什么策略執(zhí)行。
1)一次性工作
WorkRequest uploadWorkRequest = new OneTimeWorkRequest.Builder(MyWork.class) // Additional configuration .build();
- 加急工作
2.7.0
之后的版本引入了加急工作的概念,執(zhí)行一些重要的任務(wù)可以設(shè)置加急處理。
OneTimeWorkRequest request = new OneTimeWorkRequestBuilder<T>() .setInputData(inputData) .setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST) .build();
加急處理的worker
,在Android12之前通過前臺服務(wù)實現(xiàn),會在通知欄上顯示通知,所以必須實現(xiàn)getForegroundInfo
方法。
不過加急任務(wù)并不一定會立刻執(zhí)行,在某些情況下,可能還是會延遲啟動:
- 系統(tǒng)負載過高:當系統(tǒng)內(nèi)存等資源不足時
- 超出加急作業(yè)配額限制
3)定期工作
PeriodicWorkRequest saveRequest = new PeriodicWorkRequest.Builder(SaveImageToFileWorker.class, 1, TimeUnit.HOURS) // Constraints .build();
4. 創(chuàng)建約束條件
只有滿足約束條件,才會執(zhí)行任務(wù)。如果在執(zhí)行過程中,不再滿足某個約束,WorkManager
會停止工作。
Constraints constraints = new Constraints.Builder() .setRequiredNetworkType(NetworkType.UNMETERED) .setRequiresCharging(true) .build();
5. 提交WorkRequest
WorkManager .getInstance(myContext) .enqueue(uploadWorkRequest);
使用enqueue
將WorkManager
任務(wù)提交給系統(tǒng)。
多進程WorkManager
從WorkManager 2.6
版本開始,支持多進程的使用場景??梢栽谝粋€進程中設(shè)置服務(wù),讓服務(wù)在另一個進程中被調(diào)度。
1)設(shè)置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
不需要自己創(chuàng)建,但是需要在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" } }
總結(jié)
本篇文章介紹了WorkManager
的使用方法,包括如何在多進程中使用WorkManager
。
WorkManager
使用在后臺運行的任務(wù),即使App
掛掉了,也要保證能完成的任務(wù),或者是一些定時任務(wù)。
本質(zhì)原理也是通過Service
的方法拉起進程,執(zhí)行相應(yīng)的doWork
中的任務(wù)。
有一點需要注意,如果從后臺拉起進程,因為這個時候App
運行在后臺,能拿到的資源非常少,很容易就會發(fā)生后臺ANR。
雖然Service
的后臺ANR
不會彈窗提示用戶,但是會影響任務(wù)的執(zhí)行成功率。所以,建議使用多進程的方式,讓任務(wù)運行到子進程中。
在多進程的情況下,需要在RemoteWorkerService
運行的進程中,修改Application
中的onCreate
和attachBaseContext
方法,定制屬于子進程的初始化邏輯。
以上就是WorkManager解決應(yīng)用退出后繼續(xù)運行后臺任務(wù)的詳細內(nèi)容,更多關(guān)于WorkManager應(yīng)用退出后臺任務(wù)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android開發(fā)組件化架構(gòu)設(shè)計原理到實戰(zhàn)
這篇文章主要為大家介紹了Android開發(fā)組件化架構(gòu)設(shè)計原理到實戰(zhàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-06-06Android仿360懸浮小球自定義view實現(xiàn)示例
本篇文章主要介紹了Android仿360懸浮小球自定義view實現(xiàn)示例,具有一定的參考價值,感興趣的小伙伴們可以參考一下。2017-03-03Android項目實戰(zhàn)之仿網(wǎng)易頂部導(dǎo)航欄效果
這篇文章主要為大家詳細介紹了Android項目實戰(zhàn)之仿網(wǎng)易頂部導(dǎo)航欄效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-05-05android設(shè)置adb自帶screenrecord錄屏命令
這篇文章主要介紹了android設(shè)置adb自帶screenrecord錄屏命令,需要的朋友可以參考下2018-11-11Android三種方式實現(xiàn)ProgressBar自定義圓形進度條
這篇文章主要介紹了Android三種方式實現(xiàn)ProgressBar自定義圓形進度條的相關(guān)資料,需要的朋友可以參考下2016-03-03