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

这个系列我做了协程和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的好处是,它可以确保底层组件(如存储库、域层)完全在后台完成。

img

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

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

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

Pre-requisite

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

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

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

liveData {emit(data) // ORemitSource(liveData)
}
// OR
stateFlow.asLiveData()

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

1. Connect Kotlin Coroutine to LiveData

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

val someTypeLiveData: LiveData<SomeType> = liveData {// get data from is a suspend function val data = aSuspedFunction() emit(data)
}

img

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

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

val someTypeLiveData: LiveData<SomeType> =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<SomeType> =   stateFlow.asLiveData(viewModelScope.coroutineContext + Dispatchers.IO)

img

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

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

3. Transformation on Background

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

img

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

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

img

4. Connecting Multiple LiveData Source Emission

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

img

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

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 <T> liveData(context: CoroutineContext = EmptyCoroutineContext,timeoutInMs: Long = DEFAULT_TIMEOUT,@BuilderInference block: suspend LiveDataScope<T>.() -> Unit
): LiveData<T> = 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 欢迎大家访问

往期推荐

  • flutter与compose的爱恨情仇

  • 一篇掌握LiveData transformations

  • 闲言碎语——第四期

  • 让Flows感知生命周期

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

< END >

作者:徐宜生

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

LiveData Coroutine Builder的5个诡计相关推荐

  1. 【Android】使用LiveData KTX Builder让代码更简洁

    lifecycle-livedata-ktx中提供了通过Builder创建LiveData的方式, 可以方便的配合suspend函数的调用. 引入livedata-ktx implementation ...

  2. kotlin协程_使Kotlin协程无缝采用的5个技巧

    kotlin协程 After successfully adopting coroutines in my prod project I think it is time to share 5 tip ...

  3. 【Android】ViewModel KTX对Coroutine的支持

    androidx.lifecycle:lifecycle-viewmodel-ktx是ViewModel的KTX扩展库,可以让我们在ViewModel中方便的使用Coroutine.对于ViewMod ...

  4. Kotlin Coroutine(二):作用域及取消

    一.协程作用域 定义协程必须指定其 CoroutineScope .CoroutineScope 可以对协程进行追踪,即使协程被挂起也是如此.同调度程序 (Dispatcher) 不同,Corouti ...

  5. sharedpreferences使用方法_Google 推荐在 MVVM 架构中使用 Kotlin Flow

    前言 在之前分享过一篇 Jetpack 综合实战应用 Jetpack 实战:神奇宝贝 ,这个项目主要包了以下功能: 自定义 RemoteMediator 实现 network + db 的混合使用 ( ...

  6. 【译】如何在 Android 中使用 Retrofit, Moshi, Coroutines Recycler View

    翻译说明: 原标题: How-To: Retrofit, Moshi, Coroutines & Recycler View for REST Web Service Operations w ...

  7. 在 Android 开发中使用 Kotlin 协程 (一) -- 初识 Kotlin 协程

    前言 最近在研究 Kotlin 协程,发现功能真的超级强大,很有用,而且很好学,如果你正在或计划使用 Kotlin 开发 Android,那么 Kotlin 协程你一定不能错过! 协程是什么? 我们平 ...

  8. Kotlin极简教程:第9章 轻量级线程:协程

    原文链接:https://github.com/EasyKotlin 在常用的并发模型中,多进程.多线程.分布式是最普遍的,不过近些年来逐渐有一些语言以first-class或者library的形式提 ...

  9. Kotlin协程简介(一)

    目录: 一. 协程的基本概念 二. 从异步编程开始 回调 CompletableFuture RxJava 协程 三. 协程的基本概念 suspend funtion CoroutineScope C ...

最新文章

  1. SQL 判断两个时间段是否有交叉
  2. asp开发工具_VSCode搭建完美的asp.net core开发环境,看完这篇就够了
  3. 【Groovy】编译时元编程 ( 编译时方法注入 | 使用 buildFromSpec、buildFromString、buildFromCode 进行方法注入 )
  4. Erlang中使用变量的简单示例
  5. DeepEarth更新到Silverlight 4了
  6. pythonappend用法_python中append实例用法总结
  7. Remix Solidity IDE 快速入门
  8. devops实践指南_开发DevOps的实用指南:减少八卦的步骤
  9. eclipse 统计代码行数
  10. Json转化的三种方式
  11. ajax获取openid,异步环境下获取 openid的几个方法
  12. linux机顶盒线刷教程,网络机顶盒刷机教程和详细方法,实现软件任意安装,电视免费看...
  13. HaaS EDU场景式应用学习 - 复古八音盒
  14. 万字拆解欧莱雅:百年美妆帝国的数字化远征
  15. Android FFmpeg视频播放器一解封装
  16. 矩阵的模的平方matlab,matlab求矩阵、向量的模
  17. SEPIC 单端初级电感转换器 稳压器 -- Zeta 转换器
  18. 44 Defending the Theory of Evolution Still Seems Needed
  19. 通过JDBC-ODBC连接SQL Server数据库
  20. shiro权限管理实例

热门文章

  1. 互联网风格绩效考核薪酬管理PPT模板
  2. 无广告 Windows 10 系统安装
  3. iOS 项目开发总览,开发者账号
  4. mysql cube用法_SQL中CUBE 用法
  5. [ROM 制作/修改 教程] HTC One X免金卡卡刷官方RUU固件教程【S-ON/OFF通用】
  6. ios 倒数器_年倒计时器2020iOS版
  7. 【slam十四讲第二版】【课本例题代码向】【第七讲~视觉里程计Ⅱ】【使用LK光流(cv)】【高斯牛顿法实现单层光流和多层光流】【实现单层直接法和多层直接法】
  8. 嵌入式培训经验分享——C语言小项目(五子棋)
  9. asterisk odbc mysql_让asterisk支持odbc,将cdr记录写入mssql2000
  10. 查看android源代码配置