使用Work Manager-Main Components解决你的任务

148 阅读4分钟

原文地址:magdamiu.com/2019/09/22/…

作者: MAGDA MIU

“Work Manager是一个管理**推迟和有保证**的后台工作的库。”

我之前的文章中,我详细介绍了安卓内存模型、电池优化功能、当前的后台处理解决方案以及Work Manager的主要优势应该在哪里使用。

在这篇博客文章中,我将介绍Work Manager库的主要组件:

  • 工人,工人

  • 工作请求

  • 制约因素

  • Input/Output数据

  • 工作经理

为了在我们的应用程序中使用Work Manager,首先我们应该声明依赖关系

  • 打开项目的build.gradle文件,添加如下所示的google()存储库:
allprojects {
    repositories {
        google()
        jcenter()
    }
}
  • 打开模块(app)的build.gradle文件,添加必要的依赖项,如下所示:
dependencies {
    def work_version = "2.0.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 – Test helpers
    androidTestImplementation "androidx.work:work-testing:$work_version"
  }

Work Manager的主要组件有:

因此,首先我们需要通过扩展Worker类来创建一个后台任务。之后,我们通过使用Work Request实现配置如何以及何时运行任务,最后我们将任务移交给系统。

问:幕后会发生什么?在职经理使用的内部机制是什么?

答:实际上,Work Manager更像是现有后台处理解决方案的包装,用于可推迟和有保证的工作。

工人

任务由Worker类定义。函数do Work()在后台线程上同步运行。

class SyncWorker(c: Context, wp: WorkerParameters):Worker(c, wp) {
   override fun doWork(): Result {
       loadData()
       return Result.success()
   }
}

gist.github.com/magdamiu/5f…

工作请求

当任务被定义时,我们应该指定它是否是周期性的。如果它是周期性的,我们将使用周期工作请求类,如果不是,我们将使用OneTime Work Request。

一次工作请求

  • 它用于不重复的工作

  • 可能会有初始延迟

  • 它可能是工作链或图表的一部分

期刊工作请求

  • 用于需要定期执行的任务

  • 可以定义的最小重复间隔为15分钟(与Jobs Scheduler API相同),并且不能有初始延迟

  • 它不可能是工作链或图表的一部分

  • 在v2.1-alpha 02之前,不可能创建带有初始延迟的定期工作请求。

  • 执行可能会延迟,因为Work Manager受到操作系统电池优化的影响,例如打瞌睡模式

img

val syncOnlyOnce = OneTimeWorkRequestBuilder<SyncWorker>().build()

val syncPeriodically = PeriodicWorkRequestBuilder<SyncWorker>(1, TimeUnit.HOURS).build()


val periodicRefreshRequest = PeriodicWorkRequest.Builder(
  SyncWorker::class.java, // the worker class
  30, // repeating interval
  TimeUnit.Minutes,
  15, // flex interval – worker will run somehow within this period of time, but at the end of repeating interval
  TimeUnit.MINUTES
)

假设我们的任务应该只在满足某些条件时运行,也许我们需要无线连接,设备应该空闲。通过使用约束类,这在Work Manager中是可能的,并且有5个限制可以使用:

  • 网络类型限制

  • 电池电量限制: set要求电池电量不低(要求电池电量不低:布尔值)

  • 充电限制: set Charging*(要求充电:布尔*)

  • 设备限制的状态: set Device I dle(要求设备I dle:布尔

  • 存储级别限制: set Eng reres Store Not Low(reg reres Store Not Low:布尔值)

与Network Type选项相关的枚举有5个值:

  • 连接—任何工作网络连接

  • 计量网络连接

  • NOT_REQUIRED—这项工作不需要网络。

  • NOT_ROAMING—非漫游网络连接

  • 未计量——未计量的网络连接

我们可以这样应用约束:

val constraints = Constraints.Builder()
          .setRequiresCharging(true)
          .setRequiresStorageNotLow(true)
          .setRequiredNetworkType(NetworkType.CONNECTED)
          .build()

val syncOnlyOnce = OneTimeWorkRequestBuilder<SyncDataWorker>()
   .setConstraints(constraints)
   .build()

输入和输出数据

  • 数据*。Builder* helper类允许我们向Worker提供数据。

  • 请记住,这不应超过10 KB。如果我们传递的数据超过此限制,我们将获得一个Illegal State Excption。

  • 将Data想象成键值对存储,这与Shared首选项没有什么不同。

val userIdData = Data.Builder()
   .putInt(DATA_USER_ID, userId)
   .build()

val syncOnlyOnce = OneTimeWorkRequestBuilder<SyncWorker>()
   .setInputData(userIdData)
   .build()

val userIdInput = inputData.getInt(Constants.DATA_USER_ID, 0)

// ktx
val outputData = workDataOf(Constants.DATA_SENT to isDataSent)

工作经理

在工作由*Worker类**定义**之后,*我们也知道了任务的类型(周期性的或非周期性的),现在我们可以使用en队列()方法使用Work Manager来调度它。

如果我们决定取消所有工作,我们可以使用取消所有工作()方法。

img

// running work
WorkManager.getInstance().enqueue(syncOnlyOnce)


// cancelling work
WorkManager.getInstance().cancelAllWork()

关于如何检索Work Manager实例,有一件重要的事情需要提及:

Work Manager v2.1已弃用 工作管理器#get Instance() 现在有了一个新的 *工作管理器#get Instance(上下文:上下文)*以同样的方式工作,但支持新的 按需初始化**。在本文中,我将使用这种新语法,它期望我们传递一个上下文来检索Work Manager实例。

在下一篇文章中,我们将更仔细地研究像Backoff Policy这样的功能,如何识别任务,如何获得任务的状态,如何组合任务和任务的图表(链接工作),以及如何合并输入和输出。请继续关注!

现在就这样,希望有帮助!如果有什么不清楚或有问题,请随时留下评论。感谢您的阅读!