添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
爱健身的灭火器  ·  insmod error could ...·  1 年前    · 
坚强的大蒜  ·  c++ 中map 的find ...·  1 年前    · 
霸气的蘑菇  ·  RecordRef.FindFirst() ...·  2 年前    · 

workmanager是一个可延期的后台异步任务,可以用来取代以前的android后台调度任务

通俗的讲就是可以用来做后台异步任务,那他有什么优势呢,和以前的后台api方法相比有什么区别呢?

带着这俩个问题开始往下看

首先workmanager兼容性很好,包括 FirebaseJobDispatcher GcmNetworkManager JobScheduler

都可以替换成workmanager,同时支持 API 级别 14,对电量续航也做了优化(省电)

创建方式:通过单例创建workmanager,enqueue方法将任务加入队列

val myWorkRequest = ...
WorkManager.getInstance(myContext).enqueue(myWorkRequest)

任务(workrequest)是抽象基类,有俩个子类

OneTimeWorkRequest和PeriodicWorkRequest

OneTimeWorkRequest 适用于调度非重复性工作,而 PeriodicWorkRequest 则更适合调度以一定间隔重复执行的工作。

一次性工作:

val myWorkRequest = OneTimeWorkRequest.from(MyWork::class.java)

如果是复杂一点的一次性工作可以用构建器,可以在这里对你的任务添加一些策略

val uploadWorkRequest: WorkRequest =
   OneTimeWorkRequestBuilder<MyWork>()
       // Additional configuration
       .build()

定期性工作

val saveRequest =
       PeriodicWorkRequestBuilder<SaveImageToFileWorker>(1, TimeUnit.HOURS)
    // Additional configuration
           .build()
//工作的运行时间间隔定为一小时。
//可以定义的最短重复间隔是 15 分钟

request由work类组成。work类就是具体执行流程的类

如下TestWork类继承Workr类,实现doWork方法,在里面上传图片

class TestWorker(appContext: Context, workerParams: WorkerParameters):
       Worker(appContext, workerParams) {
   override fun doWork(): Result {
       // Do the work here--in this case, upload the images.
       uploadImages()
       // Indicate whether the work finished successfully with the Result
       return Result.success()doWork() 返回的 Result 会通知 WorkManager 服务工作是否成功,以及工作失败时是否应重试工作。
Result.success():工作成功完成。
Result.failure():工作失败。
Result.retry():工作失败,应根据其重试政策在其他时间尝试。

到这里,一个简单的workmanager就介绍完了,包括workmanager的创建方式,request的组成,work的创建

接下来是workmanger的一些配置

可以给任务添加约束(比如在wifi条件下才运行,在充电状态下才运行)

val constraints = Constraints.Builder()
   .setRequiredNetworkType(NetworkType.UNMETERED)
   .setRequiresCharging(true)
   .build()
val myWorkRequest: WorkRequest =
   OneTimeWorkRequestBuilder<MyWork>()
       .setConstraints(constraints)
       .build()
//可以添加的约束类型如下

下面的示例为延迟10分钟

val myWorkRequest = OneTimeWorkRequestBuilder<MyWork>()
   .setInitialDelay(10, TimeUnit.MINUTES)
   .build()

对于一组完整的异步任务,可以运行一次,也可以重复运行,对每一组任务进行命名,用来单独操作他们

//给一个单独的work添加标识
val myWorkRequest = OneTimeWorkRequestBuilder<MyWork>()
   .addTag("cleanup")
   .build()
//可以通过WorkManager.cancelAllWorkByTag(String)取消任务
//可以通过WorkManager.getWorkInfosByTag(String)获取这个任务,得到一个WorkInfo对象
//可以通过workManager.getWorkInfosByTagLiveData(String)得到一个livedata,当这个对象的tag的work执行完成之后,这个livedata会触发 

灵活的重试机制

LINEAR和EXPONENTIAL俩种策略

当你在work的dowork方法中返回Result.retry()的时候,会进行重试机制

val myWorkRequest = OneTimeWorkRequestBuilder<MyWork>()
   .setBackoffCriteria(
       BackoffPolicy.LINEAR,
       OneTimeWorkRequest.MIN_BACKOFF_MILLIS,
       TimeUnit.MILLISECONDS)
   .build()
//MIN_BACKOFF_MILLIS为10秒
//LINEAR策略,每次尝试重试的时候,重试间隔都会增加10秒,20,30,40类推
//如果是EXPONENTIAL策略,那么重试时长是20、40、80 秒,以此类推。

work中的数据传递

// Define the Worker requiring input
class UploadWork(appContext: Context, workerParams: WorkerParameters)
   : Worker(appContext, workerParams) {
   override fun doWork(): Result {
       val imageUriInput =
           inputData.getString("IMAGE_URI") ?: return Result.failure()
       uploadFile(imageUriInput)
       return Result.success()
// Create a WorkRequest for your Worker and sending it input
val myUploadWork = OneTimeWorkRequestBuilder<UploadWork>()
   .setInputData(workDataOf(
       "IMAGE_URI" to "http://..."
   .build()
//还可以通过 Result.success(outputData)将数据传递给下一个work

一次性工作状态

对于 one-time 工作请求,工作的初始状态为 ENQUEUED

ENQUEUED 状态下,您的工作会在满足其 Constraints 和初始延迟计时要求后立即运行。接下来,该工作会转为 RUNNING 状态,然后可能会根据工作的结果转为 SUCCEEDEDFAILED 状态;或者,如果结果是 retry,它可能会回到 ENQUEUED 状态。在此过程中,随时都可以取消工作,取消后工作将进入 CANCELLED 状态。
在这里插入图片描述

SUCCEEDEDFAILEDCANCELLED 均表示此工作的终止状态。如果您的工作处于上述任何状态,WorkInfo.State.isFinished() 都将返回 true。

定期工作的状态

成功和失败状态仅适用于一次性工作和链式工作定期工作只有一个终止状态 CANCELLED。这是因为定期工作永远不会结束。每次运行后,无论结果如何,系统都会重新对其进行调度。图 2 描述了定期工作的精简状态图。

确保在某一个时刻只有一个相同的实例存在

  • [WorkManager.enqueueUniqueWork()](https://developer.android.google.cn/reference/androidx/work/WorkManager#enqueueUniqueWork(java.lang.String, androidx.work.ExistingWorkPolicy, androidx.work.OneTimeWorkRequest))(用于一次性工作)
  • [WorkManager.enqueueUniquePeriodicWork()](https://developer.android.google.cn/reference/androidx/work/WorkManager#enqueueUniquePeriodicWork(java.lang.String, androidx.work.ExistingPeriodicWorkPolicy, androidx.work.PeriodicWorkRequest))(用于定期工作)

这两种方法都接受 3 个参数:

  • uniqueWorkName - 用于唯一标识工作请求的 String
  • existingWorkPolicy - 此 enum 可告知 WorkManager 如果已有使用该名称且尚未完成的唯一工作链,应执行什么操作。如需了解详情,请参阅冲突解决政策
  • work - 要调度的 WorkRequest
val sendLogsWorkRequest =
       PeriodicWorkRequestBuilder<SendLogsWorker>(24, TimeUnit.HOURS)
           .setConstraints(Constraints.Builder()
               .setRequiresCharging(true)
               .build()
           .build()
WorkManager.getInstance(this).enqueueUniquePeriodicWork(
           "sendLogs",
           ExistingPeriodicWorkPolicy.KEEP,
           sendLogsWorkRequest

上述代码在 sendLogs 作业已处于队列中的情况下运行,系统会保留现有的作业,并且不会添加新的作业

ExistingPeriodicWorkPolicy有三种选项

  • REPLACE:用新工作替换现有工作。此选项将取消现有工作。

  • KEEP:保留现有工作,并忽略新工作。

  • APPEND:将新工作附加到现有工作的末尾。此政策将导致您的新工作链接到现有工作,在现有工作完成后运行。

  • APPEND_OR_REPLACE 功能类似于 APPEND,不过它并不依赖于先决条件工作状态。即使现有工作变为 CANCELLEDFAILED 状态,新工作仍会运行。

可以通过三种方式获取查询work

// by id
workManager.getWorkInfoById(syncWorker.id) // ListenableFuture<WorkInfo>
// by name
workManager.getWorkInfosForUniqueWork("sync") // ListenableFuture<List<WorkInfo>>
// by tag
workManager.getWorkInfosByTag("syncTag") // ListenableFuture<List<WorkInfo>>

该查询会返回 WorkInfo 对象的 ListenableFuture,该值包含工作的 id、其标记、其当前的 State 以及通过 Result.success(outputData) 设置的任何输出数据

下面的代码展示了,当syncWorker完成后,显示一个消息

workManager.getWorkInfoByIdLiveData(syncWorker.id)
               .observe(viewLifecycleOwner) { workInfo ->
   if(workInfo?.state == WorkInfo.State.SUCCEEDED) {
       Snackbar.make(requireView(),
      R.string.work_completed, Snackbar.LENGTH_SHORT)
           .show()

复杂的work状态查询

以下示例说明了如何查找带有“syncTag”标记、处于 FAILEDCANCELLED 状态,且唯一工作名称为“preProcess”或“sync”的所有工作。

val workQuery = WorkQuery.Builder
       .fromTags(listOf("syncTag"))
       .addStates(listOf(WorkInfo.State.FAILED, WorkInfo.State.CANCELLED))
       .addUniqueWorkNames(listOf("preProcess", "sync")
   .build()
val workInfos: ListenableFuture<List<WorkInfo>> = workManager.getWorkInfos(workQuery)
WorkQuery` 中的每个组件(标记、状态或名称)与其他组件都是 `AND` 逻辑关系。组件中的每个值都是 `OR` 逻辑关系。例如:`(name1 OR name2 OR ...) AND (tag1 OR tag2 OR ...) AND (state1 OR state2 OR ...)

WorkQuery 也适用于等效的 LiveData 方法 getWorkInfosLiveData()

取消和停止工作

// by id
workManager.cancelWorkById(syncWorker.id)
// by name
workManager.cancelUniqueWork("sync")
// by tag
workManager.cancelAllWorkByTag("syncTag")

在work的dowork方法中通过

setProgress(firstUpdate)//设置进度
WorkManager.getInstance(applicationContext)
        // requestId is the WorkRequest id
        .getWorkInfoByIdLiveData(requestId)
        .observe(observer, Observer { workInfo: WorkInfo? ->
                if (workInfo != null) {
                    val progress = workInfo.progress
                    val value = progress.getInt(Progress, 0)
                    // Do something with progress information

您可以使用 WorkManager 创建工作链并将其加入队列。工作链用于指定多个依存任务并定义这些任务的运行顺序。当您需要以特定顺序运行多个任务时,此功能尤其有用。

如需创建工作链,您可以使用 WorkManager.beginWith(OneTimeWorkRequest)WorkManager.beginWith(List),这会返回 WorkContinuation 实例。

然后,可以使用 WorkContinuation 通过 then(OneTimeWorkRequest)then(List) 添加依存 OneTimeWorkRequest。 .

每次调用 WorkContinuation.then(...) 都会返回一个新的 WorkContinuation 实例。如果添加了 OneTimeWorkRequest 实例的 List,这些请求可能会并行运行。

最后,您可以使用 WorkContinuation.enqueue() 方法对 WorkContinuation 工作链执行 enqueue() 操作。

下面我们来看一个示例。在本例中,有 3 个不同的工作器作业配置为运行(可能并行运行)。然后这些工作器的结果将联接起来,并传递给正在缓存的工作器作业。最后,该作业的输出将传递到上传工作器,由上传工作器将结果上传到远程服务器。

WorkManager.getInstance(myContext)
   // Candidates to run in parallel
   .beginWith(listOf(plantName1, plantName2, plantName3))
   // Dependent work (only runs after all previous work in chain)
   .then(cache)
   .then(upload)
   // Call enqueue to kick things off
   .enqueue()

如果想将plantName1, plantName2, plantName3work的输出作为下一个work cache的输入。那么就需要用到输入合并器

WorkManager 提供两种不同类型的 InputMerger

也可以创建 InputMerger 的子类来编写自己的用例。

by the last最后说一下

请注意,Worker.doWork() 是同步调用 - 您将会以阻塞方式完成整个后台工作,并在方法退出时完成工作。如果您在 doWork() 中调用异步 API 并返回 Result,则回调可能无法正常运行。如果您遇到这种情况,请考虑使用 ListenableWorker(请参阅在 ListenableWorker 中进行线程处理)。

基础介绍workmanager是一个可延期的后台异步任务,可以用来取代以前的android后台调度任务通俗的讲就是可以用来做后台异步任务,那他有什么优势呢,和以前的后台api方法相比有什么区别呢?带着这俩个问题开始往下看兼容性首先workmanager兼容性很好,包括 FirebaseJobDispatcher、GcmNetworkManager 和 JobScheduler都可以替换成workmanager,同时支持 API 级别 14,对电量续航也做了优化(省电)基础功能创建方式:通过单
Android可保活的、不依附于应用进程存活的后台任务框架:WorkManager WorkManager旨在实现不依附与App进程的后台线程化任务。举例来说,假设App在本地有一个大小约2GB的文件需要上传到远程服务器。App希望在手机空闲且设备资源充足的情况下将这2GB大小的文件上传。 同时,该上传任务不受App进程存活与否影响(比如当前App进程被kill掉,仍能执行该任务)。这种类型的后...
WorkManagerJetpack架构组件中的,可以用来执行一些将来执行的任务。不适用于立即执行的任务,和退出时需要执行的任务。 (ps:感觉用处不大,一般需求都是立即执行的任务) 抱着学习的态度,我们来简单使用下: implementation "androidx.work:work-runtime:2.5.0" public class UploadWorker extends Worker { public UploadWorker(@NonNull C
方法一:For Safe args, add the following classpath in your top level build.gradle file buildscript {     repositories {         google()     dependencies {         classpath "android.arch.navigatio...
Android上有许多可延期的后台工作选项。此代码实验室涵盖WorkManager,这是一个可延迟的后台工作的兼容,灵活且简单的库。WorkManager是Android上推荐的任务调度框架,用于可延缓的工作,并且可以执行。 什么是WorkManager WorkManager是Android Jetpack的一部分,是用于后台工作的架构组件,需要兼顾机会和有保证的执行。机会... 博主之前做过这样一个需求,手机端向服务器请求数据,当没有网络时,不要请求,有网络时自动恢复请求。 应对这个需求,专门写了一个autotask模块,大体的思路就是每次请求的时候都去判断一下网络的状态,如果此时网络处于连接状态,则直接请求;如果网络处于断开状态,则将请求保存在队列当中,接收网络状态广播,一旦网络连接上,则将队列当中的请求一个一个的执行。 其实这个需求可以再抽象一...
Workmanager的作用 绝大部分应用程序都有在后台执行任务的需求。根据需求的不同,Android为后台任务提供了多种解决方法,如JobScheduler、Loader、Service等。 如果这些API没有被恰当地使用,则可能会消耗大量的电量。Android在解决应用程序耗电问题上做出了各种尝试,从Doze到App Standby,通过各种方法限制和管理应用程序,以保证应用程序不会再后台过分消耗设备的电量。WorkManager为应用程序中那些不需要及时完成的任务提供了一个统一的解决方法,以便在设备电
WorkManager是什么?它是谷歌提供的Architecture Components 架构组件的库中的其中一个库,WorkManager有什么用?官方解释如下: Note: WorkManager is intended for tasks that require a guarantee that the system will run them even if the app exit...
workmanager 18年I/O大会,google发布了 Android Jetpack.它是一些列的库,工具和架构指南,可以帮助你轻松快速的构建以优秀的App。在Android Jetpack中,Google团队中发布了一个专门用于调度和管理后台任务的库,它被称为WorkManager。 详细功能使用请自行查阅,主要用于我们执行一些...
java中有几种实现异步的方式(FutureTask/ListenableFuture/CompletableFuture) 这篇介绍的是ListenableFuture,相比FutureTask,本质上只是增加了任务的回调函数,这个是google框架里面的一个东西,我用的版本是guava-27.0-jre.jar 首先还是说使用: public class ListenableFutureTes...