WorkManager详解,BAT面试文档,腾讯安卓面试

2.2WorkRequest

也是一个抽象类,可以对Work进行包装,同时装裱上一系列的约束(Constraints),这些Constraints用来向系统指明什么条件下,或者什么时候开始执行任务。

WorkManager向我们提供了WorkRequest的两个子类:

  • OneTimeWorkRequest 单次任务。
  • PeriodicWorkRequest 周期任务。

val request1 = PeriodicWorkRequestBuilder(60,TimeUnit.SECONDS).build()

val request2 = OneTimeWorkRequestBuilder().build()

从代码中可以看到,我们应该使用不同的构造器来创建对应的WorkRequest。

接下来我们看看都有哪些约束:

  • public boolean requiresBatteryNotLow ():执行任务时电池电量不能偏低。
  • public boolean requiresCharging ():在设备充电时才能执行任务。
  • public boolean requiresDeviceIdle ():设备空闲时才能执行。
  • public boolean requiresStorageNotLow ():设备储存空间足够时才能执行。
addContentUriTrigger

@RequiresApi(24)
public @NonNull Builder addContentUriTrigger(Uri uri, boolean triggerForDescendants)

指定是否在(Uri指定的)内容更新时执行本次任务(只能用于Api24及以上版本)。瞄了一眼源码发现了一个ContentUriTriggers,这什么东东?

public final class ContentUriTriggers implements Iterable<ContentUriTriggers.Trigger> {

private final Set mTriggers = new HashSet<>();

public static final class Trigger {
private final @NonNull Uri mUri;
private final boolean mTriggerForDescendants;

Trigger(@NonNull Uri uri, boolean triggerForDescendants) {
mUri = uri;
mTriggerForDescendants = triggerForDescendants;
}

特么惊呆了,居然是个HashSet,而HashSet的核心是个HashMap啊,谷歌声明不建议用HashMap,当然也就不建议用HashSet,可是官方自己在背地里面干的这些勾当啊…

setRequiredNetworkType

public void setRequiredNetworkType (NetworkType requiredNetworkType)

指定任务执行时的网络状态。其中状态见下表:

|枚举|状态| |-|-| |NOT_REQUIRED|不需要网络| |CONNECTED|任何可用网络| |UNMETERED|需要不计量网络,如WiFi| |NOT_ROAMING|需要非漫游网络| |METERED|需要计量网络,如4G|

setRequiresBatteryNotLow

public void setRequiresBatteryNotLow (boolean requiresBatteryNotLow)

指定设备电池电量低于阀值时是否启动任务,默认false。

setRequiresCharging

public void setRequiresCharging (boolean requiresCharging)

指定设备在充电时是否启动任务。

setRequiresDeviceIdle

public void setRequiresDeviceIdle (boolean requiresDeviceIdle)

指明设备是否为空闲时是否启动任务。

setRequiresStorageNotLow

public void setRequiresStorageNotLow (boolean requiresStorageNotLow)

指明设备储存空间低于阀值时是否启动任务。

给任务加约束:

val myConstraints = Constraints.Builder()
.setRequiresDeviceIdle(true)//指定{@link WorkRequest}运行时设备是否为空闲
.setRequiresCharging(true)//指定要运行的{@link WorkRequest}是否应该插入设备
.setRequiredNetworkType(NetworkType.NOT_ROAMING)
.setRequiresBatteryNotLow(true)//指定设备电池是否不应低于临界阈值
.setRequiresCharging(true)//网络状态
.setRequiresDeviceIdle(true)//指定{@link WorkRequest}运行时设备是否为空闲
.setRequiresStorageNotLow(true)//指定设备可用存储是否不应低于临界阈值
.addContentUriTrigger(myUri,false)//指定内容{@link android.net.Uri}时是否应该运行{@link WorkRequest}更新
.build()
val request = PeriodicWorkRequestBuilder(24,TimeUnit.SECONDS)
.setConstraints(myConstraints)//注意看这里!!!
.build()

给任务加标签分组

val request1 = OneTimeWorkRequestBuilder()
.addTag(“A”)//标签
.build()
val request2 = OneTimeWorkRequestBuilder()
.addTag(“A”)//标签
.build()

上述代码我给两个相同任务的request都加上了标签,使他们成为了一个组:A组。这样的好处是以后可以直接控制整个组就行了,组内的每个成员都会受到影响。

2.3 WorkManager

经过上面的操作,相信我们已经能够成功创建request了,接下来我们就需要把任务放进任务队列,我们使用WorkManager

WorkManager是个单例,它负责调度任务并且监听任务状态。

WorkManager.getInstance().enqueue(request)

当我们的request入列后,WorkManager会给它分配一个work ID,之后我们可以使用这个work id来取消或者停止任务:

WorkManager.getInstance().cancelWorkById(request.id)

注意:WorkManager并不一定能结束任务,因为任务有可能已经执行完毕了。

同时,WorkManager还提供了其他结束任务的方法:

  • cancelAllWork():取消所有任务。
  • cancelAllWorkByTag(tag:String):取消一组带有相同标签的任务。
  • cancelUniqueWork(uniqueWorkName:String):取消唯一任务。
2.4WorkStatus

当WorkManager把任务加入队列后,会为每个WorkRequest对象提供一个LiveData(如果这个东东不了解的话赶紧去学)。 LiveData持有WorkStatus;通过观察该 LiveData, 我们可以确定任务的当前状态, 并在任务完成后获取所有返回的值。

val liveData: LiveData = WorkManager.getInstance().getStatusById(request.id)

我们来看这个WorkStatus到底都包涵什么,我们点进去看它的源码:

public final class WorkStatus {

private @NonNull UUID mId;
private @NonNull State mState;
private @NonNull Data mOutputData;
private @NonNull Set mTags;

public WorkStatus(
@NonNull UUID id,
@NonNull State state,
@NonNull Data outputData,
@NonNull List tags) {
mId = id;
mState = state;
mOutputData = outputData;
mTags = new HashSet<>(tags);
}

我们需要关注的只有StateData这两个属性,首先看State:

public enum State {

ENQUEUED,//已加入队列
RUNNING,//运行中
SUCCEEDED,//已成功
FAILED,//已失败
BLOCKED,//已刮起
CANCELLED;//已取消

public boolean isFinished() {
return (this == SUCCEEDED || this == FAILED || this == CANCELLED);
}
}

这特么又一个枚举。看过代码之后,State枚举其实就是用来给我们做最后的结果判断的。但是要注意其中有个已挂起BLOCKED,这是啥子情况?通过看它的注释,我们得知,如果WorkRequest的约束没有通过,那么这个任务就会处于挂起状态。

接下来,Data当然就是我们在任务中doWork的返回值了

看到这里,我感觉谷歌大佬的设计思维还是非常之强的,把状态和返回值同时输出,非常方便我们做判断的同时来取值,并且这样的设计就可以达到‘多次返回’的效果,有时间一定要去看一下源码,先立个flag!

3. 任务链

在很多场景中,我们需要把不同的任务弄成一个队列,比如在用户注册的时候,我们要先验证手机短信验证码,验证成功后再注册,注册成功后再调登陆接口实现自动登陆。类似这样相似的逻辑比比皆是,实话说笔者以前都是在service里面用rxjava来实现的。但是现在service在Android8.0版本以上系统不能用了怎么办?当然还是用我们今天学到的WorkManager来实现,接下来我们就一起看一下WorkManager的任务链

3.1链式启动-并发

val request1 = OneTimeWorkRequestBuilder().build()
val request2 = OneTimeWorkRequestBuilder().build()
val request3 = OneTimeWorkRequestBuilder().build()

WorkManager.getInstance().beginWith(request1,request2,request3)
.enqueue()

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
img

最后

其实Android开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。

以上分享【我的阿里P7移动开发架构师学习笔记】七大模块整套学习资料均免费分享,需要的小伙伴,我已经上传到石墨文档了,大家自取就可以了。白嫖可以,别忘了给我点个关注哈。

当然我也为你们整理好了百度、阿里、腾讯、字节跳动等等互联网超级大厂的历年面试真题集锦。这也是我这些年来养成的习惯,一定要学会把好的东西,归纳整理,然后系统的消化吸收,这样才能极大的提高学习效率和成长进阶。碎片、零散化的东西,我觉得最没有价值的。就好比你给我一张扑克牌,我只会觉得它是一张废纸,但如果你给我一副扑克牌,它便有了它的价值。这和我们收集资料就要收集那些系统化的,是一个道理。

如果你需要,我把他放在GitHub了,无偿分享的。

【Android架构视频+BATJ面试专题PDF+学习笔记】

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。
化的,是一个道理。

如果你需要,我把他放在GitHub了,无偿分享的。

【Android架构视频+BATJ面试专题PDF+学习笔记】

[外链图片转存中…(img-1Im3tuJF-1710850912881)]

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

  • 24
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值