网易首页 > 网易号 > 正文 申请入驻

LiveData Coroutine Builder的5个诡计

0
分享至

点击上方蓝字关注我,知识会给你力量

这个系列我做了协程和Flow开发者的一系列文章的翻译,旨在了解当前协程、Flow、LiveData这样设计的原因,从设计者的角度,发现他们的问题,以及如何解决这些问题,pls enjoy it。

LiveData是由Google引入的,作为连接视图(Activity/Fragment)和其ViewModel的一种手段。它就像一个简化的反应式组件(例如RxJava或Kotlin的Flow),也知道视图的生命周期。

随着最近Kotlin的Coroutine和Kotlin的Flow的推出,现在Google推出了一种使用LiveData Coroutine Builder连接Kotlin的Flow和LiveData的方法。

Benefits of using Kotlin’s Coroutine/Flow

使用Kotlin的Coroutine/Flow连接到LiveData的好处是,它可以确保底层组件(如存储库、域层)完全在后台完成。

这将有助于克服以下问题:

  • 如果主线程很忙,LiveData的postValue就会丢弃。

  • LiveData的转换功能都是在主线程中完成的。

Pre-requisite

要使用LiveData Coroutine Builder,首先我们需要包含KTX库,例如:

implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.4.0"

然后,人们可以使用它,使用:

liveData {
emit(data) // OR
emitSource(liveData)
// OR
stateFlow.asLiveData()

让我们来看看LiveData Coroutine Builder的用法吧。

1. Connect Kotlin Coroutine to LiveData

如果我们有一个需要调用的coroutine,以获取一些数据到LiveData,我们可以做以下工作。

val someTypeLiveData: LiveData = liveData {
// get data from is a suspend function
val data = aSuspedFunction()
emit(data)
img

一旦LiveData连接到任何观察者,它就会调用并接纳来自suspend函数的数据。

我们也可以确保它是在后台线程上完成的,使用:

val someTypeLiveData: LiveData =
liveData(viewModelScope.coroutineContext + Dispatchers.IO) {
// get data from is a suspend function
val data = aSuspedFunction()
emit(data)
2. Connect Kotlin Flow (or StateFlow) to LiveData

以上是一次性的获取。但如果我们有一个流程,其中数据是连续排放的,我们可以使用:

val someTypeLiveData: LiveData =
stateFlow.asLiveData(
viewModelScope.coroutineContext + Dispatchers.IO
img

一旦LiveData连接到任何观察者,它就会在stateFlow上待命,发出它的数据。在内部对于asLiveData实际上也是一个LiveData {...}。

public fun Flow.asLiveData(
context: CoroutineContext = EmptyCoroutineContext,
timeoutInMs: Long = DEFAULT_TIMEOUT
): LiveData = liveData(context, timeoutInMs) {
collect {
emit(it)

3. Transformation on Background

正如我们之前所分享的,LiveData转换是在主线程上完成的。这使得如果转换逻辑是计算密集型的,这种转换就成了问题。

为了把它移到后台,我们必须使用LiveData的switchMap和liveData的coroutine builder,如下图所示。

val liveData: LiveData =
Transformations.switchMap(sourceliveData) {
liveData(viewModelScope.coroutineContext + Dispatchers.IO)
val data = someTranformFunction(it)
emit(data)

img 4. Connecting Multiple LiveData Source Emission

在这种情况下,我们有多个LiveDatas源数据,我们想控制数据输出的逻辑,我们也可以使用Coroutine Builder。

下面是一个非常蹩脚的例子:

liveData(viewModelScope.coroutineContext + Dispatchers.IO) {
emitSource(repository.liveDataSourceA)
delay(2000)
emitSource(repository.liveDataSourceB)
delay(2000)
emitSource(repository.liveDataSourceC)

完整示例:https://github.com/elye/demo_android_compose_state_flow_livedata_viewmodel

5. Delay and Keep Coroutine Alive Temporarily

我们在liveData coroutine builder中的一个特殊功能是,它可以被配置为在LiveData不活动的特定时间内保持coroutine的活力。

这在用户改变配置或临时暂停Activity的情况下是非常有用的,而我们希望保持循环程序的活力以完成工作。但是,如果它超过了时间阈值,那么我们就想重新启动整个coroutine操作。

下面是对该条件的准确描述:

❝ liveData构建块作为coroutines和LiveData之间的结构化并发原件。该代码块在LiveData变得活跃时开始执行,当LiveData变得不活跃时,在一个可配置的超时后自动取消。如果它在完成之前被取消,那么如果LiveData再次变得活跃,它将被重新启动。如果它在之前的运行中成功完成,它不会重新启动。注意,只有在自动取消的情况下才会重新启动。如果该块因任何其他原因被取消(例如抛出一个CancellationException),它不会被重新启动。 ❞

如果我们看一下代码,我们会看到我们有timeoutInMs,它默认为5s。

@OptIn(ExperimentalTypeInference::class)
public fun liveData(
context: CoroutineContext = EmptyCoroutineContext,
timeoutInMs: Long = DEFAULT_TIMEOUT,
@BuilderInference block: suspend LiveDataScope.() -> Unit
): LiveData = CoroutineLiveData(context, timeoutInMs, block)

这意味着,当我们把活动(观察LiveData)放在后台,并且活动在暂停/停止时(注意:不是不保留活动),Coroutine将在timeoutInMs的时间内保持活力。

  • 如果超时在coroutine运行结束前完成,coroutine将在Activity恢复活动时重新启动。

img
  • 如果超时没有完成,当Activity恢复活动时,考虑到coroutine没有完成,它将继续进行直到完成。

img
  • 如果coroutine在超时前完成,即使Activity还没有恢复,coroutine也不会被重新启动,而只是发出它的最后一个值。

img TL; DR

有了LiveData coroutine builder,如果我们想的话,就不能在Kotlin Flow和LiveData之间建立桥梁。这为我们将两种技术结合在一起提供了更大的灵活性,即LiveData观察Android生命周期的能力,以及Kotlin Flor更好的反应式操作和线程处理。

https://medium.com/mobile-app-development-publication/5-uses-of-ktx-livedata-coroutine-builder-48b226bdd591

向大家推荐下我的网站 https://xuyisheng.top/ 点击原文一键直达

专注 Android-Kotlin-Flutter 欢迎大家访问

本文原创公众号:群英传,授权转载请联系微信(Tomcat_xu),授权后,请在原创发表24小时后转载。

< END >

作者:徐宜生

更文不易,点个“三连”支持一下

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
双预警齐发!10级以上雷暴大风、大到暴雨!

双预警齐发!10级以上雷暴大风、大到暴雨!

江苏警方
2026-06-03 19:26:35
中餐厅老板出售澳洲豪宅,指导价$1500万

中餐厅老板出售澳洲豪宅,指导价$1500万

澳洲红领巾
2026-06-02 14:26:36
刘亦菲参加北电同学聚会!合影站角落不抢C位,素颜脸部愈加圆润

刘亦菲参加北电同学聚会!合影站角落不抢C位,素颜脸部愈加圆润

小彭美识
2026-06-02 22:26:12
美股盘前要闻一览:特朗普声称正与伊朗达成协议;Marvell盘前再飙升10%,英特尔有望终结五连跌;欧洲拟减少对美科技巨头依赖

美股盘前要闻一览:特朗普声称正与伊朗达成协议;Marvell盘前再飙升10%,英特尔有望终结五连跌;欧洲拟减少对美科技巨头依赖

财联社
2026-06-03 20:57:09
兜转半生落泪!王菲现身谢霆锋演唱会,才懂真爱无畏岁月

兜转半生落泪!王菲现身谢霆锋演唱会,才懂真爱无畏岁月

湘西二当家
2026-06-03 16:01:33
把白银板料卖给宝妈群体,堪称21世纪最牛掰的割韭菜范例。

把白银板料卖给宝妈群体,堪称21世纪最牛掰的割韭菜范例。

流苏晚晴
2026-05-20 18:09:49
耿同学遭永久限流后,两大顶尖高校周末深夜官宣,多人集体被免职

耿同学遭永久限流后,两大顶尖高校周末深夜官宣,多人集体被免职

小徐讲八卦
2026-06-01 08:51:26
功德林降俘特赦后执意赴台,潜伏 26 年晚年揭开机要任务

功德林降俘特赦后执意赴台,潜伏 26 年晚年揭开机要任务

唠叨说历史
2026-06-01 09:52:26
黄晓明5天6瓜:被抓卖房还债,家人吃绝户最意外

黄晓明5天6瓜:被抓卖房还债,家人吃绝户最意外

大眼妹妹
2026-06-01 22:11:15
美国女子去世75年,癌细胞却活了下来,如今已分裂超过5000万吨!

美国女子去世75年,癌细胞却活了下来,如今已分裂超过5000万吨!

探谜未知世界
2026-06-03 12:58:55
A股:紧急提醒2.5亿股民!从6月4日起,A股反弹浪行情或将再度重启?

A股:紧急提醒2.5亿股民!从6月4日起,A股反弹浪行情或将再度重启?

趋势清风侠
2026-06-03 18:50:55
中纪委划红线:严查公务员出现这5种行为,触碰将一律严肃处理

中纪委划红线:严查公务员出现这5种行为,触碰将一律严肃处理

细说职场
2026-05-06 14:21:03
王晓晨俞灏明被曝就医,王晓晨街边抽烟,全程眉头紧锁,神色焦灼

王晓晨俞灏明被曝就医,王晓晨街边抽烟,全程眉头紧锁,神色焦灼

韩小娱
2026-06-02 15:22:29
中年人开始集体“降维生活”:手握二三十万存款,主动退出内卷

中年人开始集体“降维生活”:手握二三十万存款,主动退出内卷

舒山有鹿
2026-06-03 12:00:45
癌症的源头被查出,啤酒没上榜,第1名大家可能每天都在吃!

癌症的源头被查出,啤酒没上榜,第1名大家可能每天都在吃!

鬼菜生活
2026-06-02 17:31:32
又一个巴拿马?中国耗时7年倾尽百亿出海,竟成最蠢的赔本买卖

又一个巴拿马?中国耗时7年倾尽百亿出海,竟成最蠢的赔本买卖

国际风云录
2026-05-13 05:13:35
阿迪李宁的“廉价代工厂”要上市了!一双跑鞋赚不到20元,还被阿迪压着3.2亿货款

阿迪李宁的“廉价代工厂”要上市了!一双跑鞋赚不到20元,还被阿迪压着3.2亿货款

新浪财经
2026-06-03 18:52:58
沉默45年,中国终于迎来第二轮“严打”!目标改变总体战正式打响

沉默45年,中国终于迎来第二轮“严打”!目标改变总体战正式打响

闻识
2026-05-04 08:59:03
太智慧了!女方离婚“抄家”的苛刻诉求,男子回复“我听法院的”

太智慧了!女方离婚“抄家”的苛刻诉求,男子回复“我听法院的”

火山詩话
2026-06-03 10:45:04
谁来追责?浙江医院惊天乱象!花高价挂专家号,等来一场致命误诊

谁来追责?浙江医院惊天乱象!花高价挂专家号,等来一场致命误诊

牛锅巴小钒
2026-06-03 18:48:02
2026-06-04 04:24:49
Android群英传
Android群英传
Android群英传
455文章数 921关注度
往期回顾 全部

科技要闻

传DeepSeek融资意向500亿:腾讯投100亿

头条要闻

男子不想上班辞职后上武当山当道士 8个月后选择下山

头条要闻

男子不想上班辞职后上武当山当道士 8个月后选择下山

体育要闻

选择中国品牌的库里,和他们的巨大野心

娱乐要闻

官方痛批乱象 刘涛郑恺等艺人遭点名

财经要闻

AI,开始偷懒了?

汽车要闻

专访蒋平:安全不做高低配 长安要让安全技术普惠

态度原创

游戏
房产
健康
时尚
公开课

曝《塞尔达》传奇重制版将亮相!任天堂发布会下周见

房产要闻

突发!254亩调规,海口江东的超级学校真的快来了!

违规干细胞抗衰美容,为何肆无忌惮

月经、初潮与生育真相,那些藏在动画片里的性启蒙

公开课

李玫瑾:为什么性格比能力更重要?

无障碍浏览 进入关怀版