Android Jetpack - 使用WorkManager处理简单的后台任务

简介: **阿里P7移动互联网架构师进阶视频(每日更新中)免费学习请点击:[https://space.bilibili.com/474380680](https://links.jianshu.com/go?to=https%3A%2F%2Fspace.

阿里P7移动互联网架构师进阶视频(每日更新中)免费学习请点击:https://space.bilibili.com/474380680

当我们讨论后台处理任务的时候,一般可能涉及的行为类型有下面一些类型,例如:

  • 发送程序运行日志
  • 上传图片和视频
  • 同步数据
  • 处理数据

这些行为都需要在后台进行操作,在Android平台上,我们可以利用如下的这些可选方式来实现后台任务:

google_io_2018_android_jetpack_workmanager_01

那么到底我们如何做出合理的选择呢?过去的几年,Android系统随着版本的更新针对电量优化这一块做出了不同程度的限制优化,例如在Android M上的Doze Mode,Android N上的Limit Implicit Broadcast,Android O上的Background Service Limitations以及最新的Android P上面的App Standby Buckets。为了确保后台任务对电量的消耗影响足够小,对待后台任务的处理要更加的慎重小心。

0)Types of Background Work

通常来说,我们可以把所有的后台任务按照任务紧迫性(是马上需要执行的任务/还是可以缓期执行的任务)和任务重要性(是确保一定要被执行的任务/还是最好能够执行的任务)进行四象限的划分。通常来说对于非确保一定要执行的任务,无论时间是否紧迫,我们都可以使用ThreadPool来完成这个任务。对于那些比较重要的又时间紧迫的任务,我们一般会使用Foreground Service来完成这个操作。比较有有意思的是最后一个象限:那些希望确保可以被执行但是又可以接受延期执行的任务。这些任务可以使用JobScheduler/JobDispatcher/AlarmManager/BroadcastReceivers来完成。WorkManager也刚好是用来解决这一类的问题的。

google_io_2018_android_jetpack_workmanager_02

1)WorkManager Features

下面是WorkManager的一些突出特点:

  • 确保可以被执行,并且可以设置执行的限定条件(例如仅仅在有网络连接的时候才进行图片的上传)
  • 同样受到系统后台任务的限制管理(如APP进入Doze Mode的时候,任务不会被执行)
  • 向后兼容;无论是否集成了Google Play Service服务,都是向后兼容的
  • 任务可查询;如论当下在执行什么任务,都是可以直接查询获取到任务状态信息的(例如正在运行的状态是什么,结果是成功还是失败了)
  • 任务可串联;例如执行任务A之前需要任务B或者C先进行完成
  • 任务伺机执行:在条件满足的时候会尽快尝试触发任务的执行,不需要等待JobScheduler的唤醒,也不会需要等待JobScheduler进行批量任务处理的才被执行

WorkManager中的核心类有:

  • Worker:这个类是真正干活的,工作逻辑都在这里面
  • WorkRequest:

    • OneTimeWorkRequest:只执行一次的任务请求
    • PeriodicWorkRequest:重复执行的任务请求

举个例子:图片上传的后台任务是如何执行的。下面是上传图片的Worker示例:

google_io_2018_android_jetpack_workmanager_03

google_io_2018_android_jetpack_workmanager_04

其中uploadPhoto是执行在后台线程的,返回值可以是成功或者失败,还可以是重试,这意味着告诉系统这个任务需要后面找机会重新执行。有了上面那些基础,接下去就只需要利用Worker创建对应的WorkRequest,并并添加到WorkManager的执行队列中就好了。

google_io_2018_android_jetpack_workmanager_05

正常情况下,放到任务队列中的任务会被立马执行,可是如果遇到网络连接失败的情况,这样就会执行失败。此时我们就可以通过添加限定执行条件来达到优化的目的,例如设置限定只在网络连接成功的时候才进行任务的执行。

google_io_2018_android_jetpack_workmanager_06

2)Observing Work

有了上面的任务触发逻辑之后,那么如何做任务的监听呢?例如正在处理过程中显示一个进度圈,处理成功的时候消失进度等等。我们可以使用如下演示的范例来监听任务的执行状态。

google_io_2018_android_jetpack_workmanager_07

LiveData是Google开发的一个感知生命周期的架构组件。使用这个组件来hook监听request任务的WorkStatus。在WorkStatus里面有任务的id和status,其中status有6种状态,分别是ENQUEUED,RUNNING,SUCCEEDED,FAILED,BLOCKED,CANCELLED

3)Chaining Work

通常来说,上传任务真正被执行之前,我们会对数据做一次压缩,因为每一个任务都需要在后台进行,并且需要保证执行顺序。我们可以使用下面的示例方式,先进行压缩,成功之后,再进行上传。

google_io_2018_android_jetpack_workmanager_08

只所以可以类似上面那样写,是因为每一步任务返回的都是WorkContinuation,使用它可以对不同的任务进行串联。

google_io_2018_android_jetpack_workmanager_09

如果想要多项任务并发执行,可以同时建立多个WorkRequest,一起交给WorkManager进行执行(根据CPU核心数和架构的不同,并发数量有所差异)。

google_io_2018_android_jetpack_workmanager_10

我们再把任务链设置的更加复杂一点,例如图片要先分别经过不同的滤镜处理,之后再进行压缩,最后才可以上传,那么使用WorkManager该如何实行呢?

google_io_2018_android_jetpack_workmanager_11

4)Inputs and Outputs

任务之间如何进行数据的传递呢?在介绍这个之前,我们需要了解下什么叫做MapReduce。例如,我们想要从三本书里面找出使用最多的词语,先把所有词语都进行计算一遍,然后对词语的使用次数进行排序,最后才可以找出使用最多的词语,我们把这个行为叫做MapReduce。

使用WorkManager的输入和输出数据具备如下的特点:

  • 简单的KEY-VALUE

    • KEY都是String类型的
    • VALUE可以是基础数据类型和String
  • 数据本身已经做了序列化处理
  • 限定10KB大小以内

我们使用如下的方式进行输入的数据传递,构造一个map类型的Data,通过WorkManager的setInputData()给Worker进行传输数据。

google_io_2018_android_jetpack_workmanager_12

接下去Worker可以通过getInputData()来获取到输入的数据。

google_io_2018_android_jetpack_workmanager_13

一般来说,我们会需要把处理的结果进行返回,那么使用setOutputData()来完成这个操作就可以了

google_io_2018_android_jetpack_workmanager_14

有意思的事情是,在任务链中,输出的数据一般就是下一个任务的输入。那么当某个环节的一个任务是由多个任务的输出构成的时候,改如何处理呢?

google_io_2018_android_jetpack_workmanager_15

为了解决这个问题,我们需要了解InputMergers,顾名思义,它是用来合并多个输入数据变成一个的。一般来说有两种合并实现的方式(也可以自己自定义)

  • OverwritingInputMerger(系统默认):按照输入数据的先后顺序,相同KEY会被覆盖,不同的KEY内容会被保留

google_io_2018_android_jetpack_workmanager_16

  • ArrayCreatingInputMerger:相同KEY的VALUE值进行合并,需要确保VALUE是相同数据类型的,否者会出现异常

google_io_2018_android_jetpack_workmanager_17

5)Cancelling Work

想要取消一个任务,只需要调用cancelWorkById()就好了,但是需要注意的是,这个方法只是尽力而为,因为相关想要取消的任务有可能已经在运行,也有可能已经执行结束了。

google_io_2018_android_jetpack_workmanager_18

6)Tags

前面我们有提到过好几次任务id,这个id是系统自动生成的,类似UUID这样的数值。我们无法通过这个id来判断这是一个什么样的任务,tags就是为了解决这个任务可读性的问题的。我们可以给任务打上一个或者多个tag来标记这是一个什么样的任务,然后可以通过这个tag来查询,取消任务等等。

google_io_2018_android_jetpack_workmanager_19

google_io_2018_android_jetpack_workmanager_20

使用Tag可以给我们提供很大的帮助,我们可以根据不同的模块和依赖给任务设置不同的tag,也可以根据任务的类型进行设置tag,这样就可以方便的进行批量任务操作了。

7)Unique Work

为了解决多个任务的同步问题,引入了Unique Work的机制。它有三种类型,分别为

  • KEEP:新启动的Unique任务,如果之前已经存在,就继续保留旧的任务,如果不存在,则触发这次新的任务

google_io_2018_android_jetpack_workmanager_21

  • REPLACE:取消或者删除之前的所有此类Unique任务,使用这次的任务作为最新任务,重复调用多次的时候,会以最后一次为准

google_io_2018_android_jetpack_workmanager_22

  • APPEND:按照添加顺序,逐个执行任务

google_io_2018_android_jetpack_workmanager_23

8)Periodic Work

重复任务和我们之前认知的其他重复任务一样,具备一些如下的特点:

  • 最短间隔时间15分钟(和JobScheduler一样)
  • 同样受系统doze mode和其他的后台任务限制
  • 不可以有任务链
  • 不可以有触发延迟

9)Under The Hood

当系统接受到一个Work任务的时候,会先记录到自己的任务数据库中,接下去系统是如何判断执行的呢?如果任务符合当下执行的条件,那么会由Executor(可自定义,系统默认有实现)立即执行;如果我们的进程已经被杀死,那么任务什么时候可以被执行呢?如果设备运行在>=API 23,会交给JobScheduler触发IPC请求,唤醒我们的进程进行任务的执行;如果设备运行在< API 23的情况下,系统会判断设备是否有Firebase JobDispatcher,如果有会交给它进行处理;如果那些Google Play Service服务都没有,系统会使用AlarmManager和BroadcastReceivers的方式在合适的时候唤醒应用进行处理。

google_io_2018_android_jetpack_workmanager_24

10)Best Practice

  • 何时使用WorkManager呢?下面给一些最佳实践的例子:

    • OK:上传图片和视频
    • OK:解析数据并存储到数据库中
    • NO:从调色板中获取颜色并设置到图片上
    • NO:解析数据并呈现到视图上进行显示
    • NO:处理交易的请求
  • 不要使用WorkManager来存储数据,记得只有10kb的限制
  • 记得给不同的任务设置各自的执行限定条件,避免无谓的资源浪费

google_io_2018_android_jetpack_workmanager_25
原文作者:胡凯
原文链接http://hukai.me/google-io-2018-android-jetpack-workmanager/
阿里P7移动互联网架构师进阶视频(每日更新中)免费学习请点击:https://space.bilibili.com/474380680

相关文章
|
18天前
|
存储 设计模式 数据库
构建高效的安卓应用:探究Android Jetpack架构组件
【4月更文挑战第20天】 在移动开发的世界中,构建一个既高效又可维护的安卓应用是每个开发者追求的目标。随着Android Jetpack的推出,Google为开发者提供了一套高质量的库、工具和指南,以简化应用程序开发流程。本文将深入探讨Jetpack的核心组件之一——架构组件,并展示如何将其应用于实际项目中,以提升应用的响应性和稳定性。我们将通过分析这些组件的设计原则,以及它们如何协同工作,来揭示它们对于构建现代化安卓应用的重要性。
|
4月前
|
Android开发 开发者
什么是Android Jetpack,它包括哪些组件?
什么是Android Jetpack,它包括哪些组件?
42 0
|
4月前
|
IDE API 开发工具
Google I/O :Android Jetpack 最新变化(四)Compose
Google I/O :Android Jetpack 最新变化(四)Compose
110 0
|
4月前
|
JSON IDE 测试技术
Google I/O :Android Jetpack 最新变化(二) Performance
Google I/O :Android Jetpack 最新变化(二) Performance
116 0
|
8天前
|
安全 Android开发 开发者
构建高效Android应用:采用Kotlin与Jetpack的实践指南
【4月更文挑战第30天】 在移动开发领域,随着技术的不断进步,为了提高应用的性能和用户体验,开发者们不断地探索新的工具和框架。对于Android平台而言,Kotlin语言以其简洁性和功能性成为了开发的首选。而Jetpack组件则提供了一套高质量的库、工具和指南,帮助开发者更轻松地构建高质量的应用程序。本文将探讨如何结合Kotlin语言和Jetpack组件来优化Android应用的开发流程,提升应用性能,并保证代码的可维护性和可扩展性。
|
8天前
|
数据库 Android开发 开发者
构建高效Android应用:采用Kotlin与Jetpack的实践指南
【4月更文挑战第30天】 随着移动开发技术的不断演进,Android平台提供了多种工具和框架以提升应用性能和开发效率。在本文中,我们将深入探讨如何结合Kotlin语言的简洁性和Android Jetpack组件的强大功能来构建一个既高效又可维护的Android应用。通过分析现代Android应用架构的关键要素,我们将展示如何利用Kotlin的特性以及如何整合Jetpack中的LiveData、ViewModel和Room等组件,以实现响应式编程、数据持久化和生命周期管理。
|
9天前
|
存储 数据库 Android开发
构建高效Android应用:采用Kotlin与Jetpack的实践指南
【4月更文挑战第29天】 在现代移动开发领域,构建一个既高效又稳定的Android应用对于开发者来说是一个持续的挑战。随着技术的不断进步和用户需求的日益增长,传统的开发方法已不足以满足市场的要求。本文将深入探讨如何结合Kotlin编程语言以及Android Jetpack组件,来提升Android应用的性能、稳定性及开发效率。通过分析Kotlin的优势、介绍Jetpack的核心组件,并结合实际案例,我们将展示如何在实际项目中应用这些技术,以期达到优化应用架构、提高代码质量和加快开发流程的目的。
18 1
|
4月前
|
API Android开发
Google I/O :Android Jetpack 最新变化(三)UI
Google I/O :Android Jetpack 最新变化(三)UI
51 0
|
17天前
|
设计模式 前端开发 数据库
构建高效Android应用:使用Jetpack架构组件实现MVVM模式
【4月更文挑战第21天】 在移动开发领域,构建一个既健壮又易于维护的Android应用是每个开发者的目标。随着项目复杂度的增加,传统的MVP或MVC架构往往难以应对快速变化的市场需求和复杂的业务逻辑。本文将探讨如何利用Android Jetpack中的架构组件来实施MVVM(Model-View-ViewModel)设计模式,旨在提供一个更加模块化、可测试且易于管理的代码结构。通过具体案例分析,我们将展示如何使用LiveData, ViewModel, 和Repository来实现界面与业务逻辑的分离,以及如何利用Room数据库进行持久化存储。最终,你将获得一个响应迅速、可扩展且符合现代软件工
21 0
|
21天前
|
Android开发 开发者
什么是Android Jetpack,它包括哪些组件?
【4月更文挑战第17天】Android Jetpack是Google提供的一套工具集,助力开发者高效、稳定地开发Android应用。它包含架构、UI、行为和基础组件,简化了后台任务、导航和生命周期管理,使开发者能专注于创新。随着不断更新,如CameraX的推出,掌握Jetpack对开发者面试和工作至关重要。
22 0