热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

自定义WorkManager基础概念

WorkManager 是一个 AndroidJetpack 扩大库,它能够让您轻松布局那些可延后、异步但又须要牢靠运行的工作。对于绝大部分后盾执行工作来说,应用WorkManag
文章目录[隐藏]
  • 自定义配置和 WorkerFactory
  • WorkManager 的 WorkerFactory
  • 禁用默认初始化
  • 总结

WorkManager 是一个 Android Jetpack 扩大库,它能够让您轻松布局那些可延后、异步但又须要牢靠运行的工作。对于绝大部分后盾执行工作来说,应用 WorkManager 是目前 Android 平台上的最佳实际。

目前为止本系列曾经探讨过:

  • Android Jetpack WorkManager | Android 中文教学视频
  • WorkManager 在 Kotlin 中的实际 
  • WorkManager: 周期性工作

在本篇文章中,咱们将会探讨自定义配置相干的内容,包含:

  • 为什么可能会须要自定义配置
  • 如何申明自定义配置
  • WorkerFactory 以及自定义 WorkerFactory 的起因
  • DelegatingWorkerFactory 详解

本系列的下一篇文章将对依赖注入和 Dagger 展开讨论,请继续关注咱们。

应用 WorkManager 时,您须要本人定义 Worker/CoroutineWorker 或任何 ListenableWorker 的派生类。WorkManager 会在正确的工夫点实例化您的 Worker,其机会独立于您利用的运行,不受其运行状态的影响。为了能够初始化您的 Worker,WorkManager 会应用一个 WorkerFactory。

默认 WorkerFactory 所创立的 Worker 只蕴含两个参数:

  • Application 的 Context
  • WorkerParameters

如果您须要通过 Worker 的构造函数传入更多参数,则须要一个自定义的 WorkerFactory。

延长浏览 : 咱们讲过默认的 WorkerFactory 应用反射来实例化正确的 ListenableWorker 类,但当咱们的 Worker 类的类名被 R8 (或 ProGuard) 最小化之后,这个操作就会失败。为了防止这种状况,WorkManager 蕴含了一个 proguard-rules.pro 文件来防止您的 Worker 类的类名被混同。

自定义配置和 WorkerFactory

WorkManager 类遵循 单例模式,而且它只能在实例化之前进行配置。这意味着,如果您想自定义它的配置,就必须先禁用默认配置。

如果您尝试通过 initialize() 办法再次初始化 WorkManager,该办法就会抛出一个异样 (于 1.0.0 版本中退出)。为了防止异样,您须要禁用默认的初始化。您能够稍后在您的 Application 的 onCreate 办法中配置和初始化您的 WorkManager。

2.1.0 版本 中退出了一个更好的初始化 WorkManager 的形式。您能够通过在您的 Application 类中实现 WorkManager 的 Configuration.Provider 接口的形式来应用按需初始化。接下来,您只须要应用 getInstance(context)) 取得实例,WorkManager 就会通过您的配置初始化它本人。

可配置参数

如上所讲,您能够配置用来创立 Worker 的 WorkerFactory,然而您也能够自定义其余的参数。WorkManager 的 Configuration.Builder 参考指南中蕴含了参数的残缺列表。这里我想强调两个附加参数:

  • Logging 级别
  • JobId 范畴

当咱们有须要时,能够通过批改日志级别不便地了解 WorkManager 中正在产生什么。对于这个话题,咱们有一个 专门的文档页。您也能够查看 Advanced WorkManager codelab 实战教程,以理解此性能在实在示例中的实现,以及您能够通过此性能获取到什么样的信息。

如果以在咱们的利用中应用 JobScheduler API 一样的形式应用 WorkManager,咱们可能也会想要自定义 JobId 范畴。因为在这种状况下,您会想要防止在同一个中央应用雷同的 JobId 范畴。版本 2.4.0 中也退出了一个新的 Lint 规定 来笼罩这种状况。

WorkManager 的 WorkerFactory

咱们曾经晓得,WorkManager 有一个默认的 WorkerFactory,它能够依据咱们经由 WorkRequest 传入的 Worker 类的类名,通过反射来找到应该实例化的 Worker 类。

⚠️  如果您在创立了一个 WorkRequest 后重构了利用,并为您的 Worker 类起了另一个名字,WorkManager 就会因为无奈找到正确的类而抛出一个 ClassNotFoundException。

您可能会想要为您的 Worker 的构造函数增加其余参数。假如您有一个 Worker 须要援用一个 Retrofit 服务来跟近程服务器进行通信:

/* Copyright 2020 Google LLC.  
   SPDX-License-Identifier: Apache-2.0 */
class UpvoteStoryWorker(
  appContext: Context, 
  workerParams: WorkerParameters, 
  private val service: UpvoteStoryHttpApi) 
    : CoroutineWorker(appContext, workerParams) {

    override suspend fun doWork(): Result {

        return try {
           // 投票操作
            Result.success()
        } catch (e: Exception) {
            if (runAttemptCount 

如果咱们在一个利用上作出下面的批改,程序依然可被失常编译。然而只有代码被执行、WorkManager 尝试去实例化这个 CoroutineWorker 时,利用就会因为抛出异样而被敞开。异样的形容为无奈找到正确的办法来进行实例化:

Caused by java.lang.NoSuchMethodException:  [class android.content.Context, class androidx.work.WorkerParameters]

这时咱们就须要一个自定义的 WorkerFactory。

然而别着急,咱们曾经看到其中波及的几个步骤。当初让咱们回顾一下咱们曾经做了的事件,而后深刻理解其中每一步的详细信息:

  1. 禁用默认初始化
  2. 实现一个自定义 WorkerFactory
  3. 创立自定义配置
  4. 初始化 WorkManager

禁用默认初始化

如 WorkManager 的文档 中形容,禁用操作要在您的 AndroidManifest.xml 文件中实现。移除默认状况下从 WorkManager 库中主动合并的节点。



实现一个自定义 WorkerFactory

为了创立蕴含正确参数的 Worker,当初须要实现咱们本人的工厂 (factory):

/* Copyright 2020 Google LLC.  
   SPDX-License-Identifier: Apache-2.0 */
class MyWorkerFactory(private val service: UpvoteStoryHttpApi) : WorkerFactory() {

    override fun createWorker(
        appContext: Context,
        workerClassName: String,
        workerParameters: WorkerParameters
    ): ListenableWorker? {
               // 这里只能解决一个 Worker,请不要这样做!
               // 参考下文来更好地应用 DelegatingWorkerFactory
        return UpvoteStoryWorker(appContext, workerParameters, DesignerNewsService)

    }
}

创立一个自定义 WorkerConfiguration**

接下来,咱们必须将咱们的工厂注册到咱们的 WorkManager 的自定义配置中:

/* Copyright 2020 Google LLC.  
   SPDX-License-Identifier: Apache-2.0 */
class MyApplication : Application(), Configuration.Provider {
    override fun getWorkManagerConfiguration(): COnfiguration= 
        Configuration.Builder()
                     .setMinimumLoggingLevel(android.util.Log.DEBUG)
                     .setWorkerFactory(MyWorkerFactory(DesignerNewsService))
                     .build()
...
}

初始化 WorkManager

当您的利用中只有一个 Worker 类时,以上便是您所须要做的所有事件。而如果您有多个或者预计将来会有多个 Worker 类,更好的解决方案是应用在 2.1 版中退出的 DelegatingWorkerFactory。

应用 DelegatingWorkerFactory

咱们能够通过应用 DelegatingWorkerFactory 来代替将 WorkManager 配置为间接应用某个工厂的操作。咱们能够应用 DelegatingWorkerFactory 的 addFactory()) 办法向其增加咱们的工厂,这样一来,您就有了多个工厂,其中每个都能够治理一个或多个 Worker。在 DelegatingWorkerFactory 中注册您的工厂,这将有助于协调多个工厂的执行。

在这种状况下,您的工厂须要查看是否晓得如何解决作为参数传入的 workerClassName。如果答案是否定的,就返回 null,而 DelegatingWorkerFactory 便会去寻找下一个注册的工厂。如果没有任何被注册的工厂晓得如何解决某个类,那么它将回退到应用反射的默认工厂。

上面是咱们的工厂类代码,批改为当它不晓得如何解决某个 workerClassName 时,将返回 null:

/* Copyright 2020 Google LLC.  
   SPDX-License-Identifier: Apache-2.0 */
class MyWorkerFactory(private val service: DesignerNewsService) : WorkerFactory() {

    override fun createWorker(
        appContext: Context,
        workerClassName: String,
        workerParameters: WorkerParameters
    ): ListenableWorker? {

        return when(workerClassName) {
            UpvoteStoryWorker::class.java.name ->
                ConferenceDataWorker(appContext, workerParameters, service)
            else ->
                // 返回 null,这样基类就能够代理到默认的 WorkerFactory
                null
        }

    }
}

咱们的 WorkManager 配置会变成:

/* Copyright 2020 Google LLC.  
   SPDX-License-Identifier: Apache-2.0 */
class MyApplication : Application(), Configuration.Provider {

    override fun getWorkManagerConfiguration(): Configuration {
        val myWorkerFactory = DelegatingWorkingFactory()
     myWorkerFactory.addFactory(MyWorkerFactory(service))
     // 在这里增加您利用中可能会应用的其余 WorkerFactory

            return Configuration.Builder()
                    .setMinimumLoggingLevel(android.util.Log.INFO)
                    .setWorkerFactory(myWorkerFactory)
                    .build()
    }
...
}

如果您有多个 Worker 须要不同的参数,您能够创立第二个 WorkerFactory,并通过再次调用 addFactory 来增加它。

总结

WorkManager 是一个性能非常弱小的库,它的默认配置曾经能够笼罩许多常见的应用场景。然而当您遇到某些状况时,诸如须要减少日志级别或须要传入额定参数到您的 Worker 时,则须要一个自定义的配置。

心愿您能通过本文对此主题有一个良好的意识。如果您有任何疑难,能够在评论区中留言。

接下来的文章咱们将会探讨如何在自定义 WorkManager 配置时应用 Dagger,感兴趣的读者请持续关注。



推荐阅读
  • 配置OracleACFS集群文件系统
    配置OracleACFS集群文件系统               2012-07-1010:18:39标签:asmacfs版权声明:原创作品,谢绝转载!否则将追究法律责任。     ... [详细]
  • rtemsapi用户指南Elixir代表了相对较新的编程语言,面向更广泛的受众。它于2011年发布,此后一直在开发中。他的主要特征是取消功能范式 ... [详细]
  • Day17_16_SpringCloud教程之Feign高级功能详解
    Feign高级功能详解注意:本篇Feign的高级功能实现请参考上一篇博客.Feign的高级功能实现以上一篇博客代码为基础,我们主要修改service_feign_consume ... [详细]
  • Spring @Primary和@Qualifier注解原理解析
    这篇文章主要介绍了Spring@Primary和@Qualifier注解原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值, ... [详细]
  • Android 自定义控件基础 canvas paint
    1、首先说一下canvas类:ClassOverviewTheCanvasclassholdsthedrawcalls.Todrawsomething,youne ... [详细]
  • 软件自动化测试的学习路线
    软件自动化测试的学习步骤软件测试交流群关注软件测试技术公众号获取阅读目录软件自动化测试的学习步骤自动化测试的本质自动化测试学习的误区自动化测试的职位自动化测试分类Web自动化 ... [详细]
  • FluxCD、ArgoCD或Jenkins X,哪个才是适合你的GitOps工具?
    GitOps是一种使用基于Git的工作流程来全面管理应用和基础设施的想法,其在最近获得了极大关注。新一代的部署工具更能说明这一点,它们将GitOps作为 ... [详细]
  • 在写每日签到的时候,我居然使用的是本地时间被项目经理笑哭了。。。。,如果你在写单机游戏,没有游戏服务器,但又不想使用本地时间,就可以采用下面方法.方法总结:     1.使用 ... [详细]
  • 开发笔记:Xunit测试使用个人小结
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了Xunit测试使用个人小结相关的知识,希望对你有一定的参考价值。因工作中用到xunit测试,故总结下用法,以供个人参考使 ... [详细]
  • 怎么用php登录微博(2023年最新整理)
    导读:今天编程笔记来给各位分享关于怎么用php登录微博的相关内容,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!本文目录一览: ... [详细]
  • Eclipse中SpringBoot响应jsp的简单demo
    首先在Eclipse里新建一个maven工程,这里的打包类型和父包如果后续再去pom中添加也可以此时的工程路径是这样的接下来去到pom中添加相关的依赖,如果有报错mavenupda ... [详细]
  • 突然觉得服务器ssh密码登录总是浪费一定量的时间,就想试试用sshKey进行登录。生成服务器sshkey和本地sshkey$ssh-keygen在服务器上生成一个authorize ... [详细]
  • CAS介绍CAS(CentralAuthenticationService),是耶鲁大学开发的单点登录系统(SSO,singlesign-on),应用广泛,具有独立于平台的,易于理解,支持代 ... [详细]
  • 本文整理了Java中javax.swing.Action.addPropertyChangeListener()方法的一些代码示例,展示了Action.ad ... [详细]
  • 【从零到壹】Koa 从理解到实现
    【从零到壹】Koa从理解到实现-【点击查看文中的相关源码】根据官网的介绍,Koa是一个新的Web框架,致力于成为Web应用和API开发领域中的一个更小、更富有表现力和更健壮的基石。 ... [详细]
author-avatar
半暖半夏半流年
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有