androidx.lifecycle:lifecycle-viewmodel-ktx是ViewModel的KTX扩展库,可以让我们在ViewModel中方便的使用Coroutine。对于ViewModel-KTX的使用,我们需要关注以下三个知识点:

  1. ViewModelScope的使用
  2. suspend函数的调用
  3. Flow的订阅

接下来通过一个MVVM架构的示例,围绕上面这三点进行一个简单介绍。
我们会在Model层使用Repository进行管理,在ViewModel层通过LiveData驱动UI更新。

androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0-rc03
Coroutine:1.3.3

1. ViewModelScope的使用


ViewModel-KTX中提供了一个ViewModel的扩展函数viewModelScope,定于如下:

/*** [CoroutineScope] tied to this [ViewModel].* This scope will be canceled when ViewModel will be cleared, i.e [ViewModel.onCleared] is called*/
val ViewModel.viewModelScope: CoroutineScope

viewModelScope可以在ViewModel.onClear的时候调用CoroutineScope.cancel,从而中断所有运行中的Coroutine以避免泄露。

viewModelScope会将挂起函数dispatch到MainThread运行,所以可以直接调用LiveData.setValue

val userLiveData = MutableLiveData(...)viewModelScope.launch {val user = userRepository.getUser() // 调用suspend函数userLiveData.setValue(user) // 主线程运行,所以可以setValue// userLiveData.postValues(user)
}

使用viewModelScope时,无需使用LiveData.postValue

2. suspend函数调用


通过suspend函数可以进行API请求的耗时操作,Retrofit以及Room三方库在新版本中都增加了suspend函数的API。我们定义Repository如下,通过Retrofit返回suspend接口:

interface UserApi {suspend fun getUser(): User
}class UserRepository(private val retrofitService: UserApi) {suspend fun getUser() : User {val user = retrofitService.getUser()...return user}
}

然后可以在ViewModelScope中对Repository进行调用

viewModelScope.launch {val user = userRepository.getUser()...
}

Repository请求过程中的异常,需要通过try...catch进行捕获

viewModelScope.launch {try {val user = userRepository.getUser()...} catch (e: Exception) {...}
}

此外,也可以使用runCatching,这种方式使用起来更加优雅

viewModelScope.launch {runCatching { userRepository.getUser() }.onSuccess { ... }.onFailure { ... }
}

另外,也可以在Repository中捕获异常,然后通过包装类返回结果,如下:

class UserRepository(private val retrofitService: UserApi) {suspend fun getUser() : NetWorkResult<User> {try {val user = retrofitService.getUser()return NetWorkResult.Success(user)} catch (e: Exception) {return NetWorkResult.Error(e)}}
}

LiveData的Builder方式

LiveData KTK提供了LiveData的Builder方式,我们可以将ViewModelScope中的实现写到builder中,调用emit为liveData赋值,让代码达到极致的简洁(参考: 使用LiveData Builder让代码更简洁)

val user = liveData<User> {runCatching { repository.getUser() }.onSuccess { emit(it) }.onFailure { ... }...
}

3. Flow的订阅


Flow可以在Coroutine中处理stream式数据,相当于RxJava的Observable或者Flowable
我们可以在init初始化块中对Flow进行订阅,可以避免造成重复订阅。同时在init中也可以通过SavedStateHandle进行状态初始化

class MyViewModel(private val state: SavedStateHandle) : ViewModel() {init {...}
}

触发订阅可以使用collectcollectLatest或者launchIn

class MyViewModel(...) : ViewModel() {init {viewModelScope.launch {repository.getFlowStream().collect { ... }}repository.getFlowStream().onEach { ... }.launchIn(viewModelScope)}
}

通过catchonCompletion处理异常以及结束通知

repository.getFlowStream().onEach { ... }.catch { ... }.onCompletion { ... }.launchIn(viewModelScope)

个人推荐使用launchIn,写法上更加声明式、缩进更少

总结


  • 使用viewModelScope可以在必要的时候对Coroutine自动进行后处理
  • 异常捕获需要使用try...catchrunCatching的写法上更优雅
  • 使用launchIn可以让Flow的订阅更加声明式

【Android】ViewModel KTX对Coroutine的支持相关推荐

  1. Android MVVM + Retrofit + OkHttp + Coroutine 协程 + Room + 组件化架构的Android应用开发规范化架构

    BaseDemo 介绍 BaseDemo 是Android MVVM + Retrofit + OkHttp + Coroutine 协程 + Room + 组件化架构的Android应用开发规范化架 ...

  2. Google Maps API v2 android版本开发 国内手机不支持google play Service相关问题解决--图文教程

    Google Maps API v2 android版本开发 国内手机不支持google play Service相关问题解决--图文教程 参考文章: (1)Google Maps API v2 an ...

  3. Android Nougat 有望本月到来:支持手动曝光调节

    有报道称手动曝光控制功能将重返Android Nougat自带的相机应用,而这款移动操作系统有望于本月正式与大家见面.据Android Police报道,当你点击屏幕对角的时候,曝光控制的选项也会在右 ...

  4. Android8.0 学习 (17)Android国际化(多语言)实现,支持8.0

    Android国际化(多语言)实现,支持8.0 前言 最近因为项目中使用了国际化,所以正好研究了下实现方法: 首先说下项目需求: 可以随着系统切换语言而切换语言,不支持的语言显示默认 用户可以选择语言 ...

  5. Android ViewModel

    In this tutorial, we'll be digging deep into the concept of ViewModel. We'll be developing a Favouri ...

  6. android7.0 谷歌拼音,谷歌浏览器在Android 7.0及以上版本支持使用指纹验证进行无密码登录...

    原标题:谷歌浏览器在Android 7.0及以上版本支持使用指纹验证进行无密码登录 来源:蓝点网 此前谷歌已经宣布与 FIDO 联盟达成合作关系并在安卓系统上调用指纹或面部识别等来登录某些支持的网站. ...

  7. flyme7的Android版本,Flyme开始适配Android 7.0,首批就支持这么多机型

    原标题:Flyme开始适配Android 7.0,首批就支持这么多机型 系统作为一款手机的灵魂,用户的体验往往来源于此,而知国产手机中广受好评的定制ROM无疑是Flyme和MIUI,其中魅族Flyme ...

  8. appcompat v21: 让 Android 5.0 前的设备支持 Material Design

    1. 十大Material Design开源项目 2. appcompat v21: 让 Android 5.0 前的设备支持 Material Design 主题 AppCompat已经支持最新的调 ...

  9. 安卓Android ViewModel 超简单实例

    安卓Android ViewModel 超简单实例 文章目录 安卓Android ViewModel 超简单实例 前言 使用步骤 1.引入库 2.继承ViewModel 并定义一个对象 3.到处去用 ...

最新文章

  1. 再见!Python不想再被这么搞了!
  2. java 增量编译_java增量构建关于lambda表达式的问题
  3. 无线循环里面 string = “i”会内存溢出吗?_记一次公司JVM堆溢出抽茧剥丝定位的过程...
  4. Linux 系统应用编程——线程基础
  5. android实现手机拍照以及图片预览功能_手机系统将有A/B分区?Android 11这些变化你关注过吗...
  6. C语言:斗地主发牌程序
  7. Tensorflow 循环神经网络03 LSTM长短时记忆神经网络
  8. 在linux系统下安装与配置SVN服务器
  9. 计算机软考数据库怎么学,计算机软考数据库系统工程师学习笔记(二)
  10. java pdf 转tif_使用java对pdf转成tiff文件
  11. python把工作簿拆分为工作表_使用Python和Pandas将Excel工作表拆分为单独的工作表...
  12. Ubuntu安装cuckoo布谷鸟沙箱详细步骤
  13. 网页制作html基础知识思维导图
  14. p6000 深度学习_英伟达推Quadro新显卡,支持VR、深度学习等技术
  15. shell for循环命令行_七年老运维实战中的 Shell 开发经验总结
  16. Linux usb 3. Host 详解
  17. 玉米社:网站seo站内优化技巧有哪些?
  18. 淘宝主图SKU图采集下载
  19. 看见阿里的语音识别系统很好
  20. Python 神仙姐姐图像手绘效果实现

热门文章

  1. 上班那些事儿之工作八小时
  2. python123绘制五角星,Python第八课 绘制五角星1.0
  3. 微信小程序|基于小程序+云开发制作一个菜谱小程序
  4. Liunx Jenkins没有overall/Read权限
  5. python编程例子书籍-哇塞!最受欢迎的Python编程书籍!值得收藏
  6. 【冲刺蓝桥杯】牛客竞赛补题 + 算法模板总结
  7. 世界500强ING集团顺利的敏捷转型之路
  8. python123外汇兑换程序,货币兑换程序python
  9. 程序员开上有牌面的车,车贷怎么偿还?
  10. 喝汽水,1瓶汽水1元,2个空瓶可以换一瓶汽水,给20元,可以多少汽水(编程实现) 学会了让小卖部老板送汽水