Kotlin Flow实际开发的几个场景问题
来源:13-9 案例:协程在 Android 中的应用

默小铭
2021-11-24
以下代码就是在ViewModel定义两个方法,写法一是直接将结果通过StateFlow传给View层处理,写法二和老师课程类似,直接把密封类传给View层,让View层判断密封类对应状态处理
写法一:
//把数据的处理也交给仓库层了,
private val _stateFlowObs = MutableStateFlow<List<String>>(emptyList())
val stateFlowObs: StateFlow<List<String>> = _stateFlowObs
fun getDogImages3(isSuccess: Boolean) = viewModelScope.launch {
//NetRequestRepository.getDogFire(isSuccess)
NetRequestRepository.getDogImages(isSuccess)
.onStart {
//flow 调用数据之前回调,
// 可用作 正在加载数据... Loading视图
}.catch {
//捕获上游出现的异常,这里指请求框架
}
.onCompletion {
//请求完成
//可用作 正在加载数据... Loading视图关闭
}
.collectLatest { result ->
//在一段时间内发送多次数据,只会接受最新的一次发射过来的数据
result.doFailure { throwable ->
_failure.value = throwable?.message ?: "failure"
}
result.doSuccess { value ->
//这个相当于 LiveData.setValue()
_stateFlowObs.value = value
}
}
}
//------------StateFlow 仿LiveData 写法(直接把密封类发送出去,让宿主自己处理)---------------
写法二:
private val _uiState =
MutableStateFlow<ResultWrapper2>(ResultWrapper2.Success<List<String>>(emptyList()))
val uiState: StateFlow<ResultWrapper2> = _uiState
fun getDogImages4(isSuccess: Boolean) = viewModelScope.launch {
NetRequestRepository.getDogImages2(isSuccess)
.onStart {
//flow 调用数据之前回调,
// 可用作 正在加载数据... Loading视图
}.catch {
//捕获上游出现的异常,这里指请求框架
}
.onCompletion {
//请求完成
//可用作 正在加载数据... Loading视图关闭
}
.collectLatest { result ->
_uiState.value = ResultWrapper2.Success(result)
}
}
疑问场景一:
如果说一个页面只有一个网络请求,那么可以判断密封类状态,或者如果在onStart()/onCompletion()中对加一个状态控制LoadingDialog显示/隐藏,那么如果一个页面有多个请求的情况该怎么做呢??
目前自己想过的方案
- 协程实现 异步任务串行执行,然后在第一个请求实现 onStart() ,在最后一个请求实现 onCompletion(),来控制LoadingDialog的显示隐藏
- 协程实现 异步任务串行执行,调请求时自己先显示LoadingDialog,待执行完所有请求后
疑问场景二:
一个网络请求的的结果是另一个网络请求的参数,比方微信授权登录,登录成功后拿到userId,然后拿userid调微信接口,获取更详细的用户信息
目前自己想过的方案
- 老方案,ViewModel定义两个方法 funA()获取userID,然后View层,再将userID传给funB()获取用户详情
- Flow嵌套使用,自己瞎试,还没验证过的,如下伪代码
fun getDogImages4(isSuccess: Boolean) = viewModelScope.launch {
//FlowA
NetRequestRepository.getDogImages2(isSuccess)
.collect { result ->
_uiState.value = ResultWrapper2.Success(result)
//FlowB
NetRequestRepository.getDogFire(true).collect {
//do someThing
}
}
}
写回答
2回答
-
bennyhuo
2021-11-25
课程设计的时候还没有 StateFlow,我目前还没有在项目里面用到(还是livedata),不过感觉上应该比较类似。
至于你说的多个异步的情况,能用挂起函数串行去写就不要用回调。
00 -
bennyhuo
2021-11-25
Flow实际上是协程对响应式思想的实现,如果你以前用过RxJava,可以简单地理解为支持了suspend 函数的RxJava。
00
相似问题
kotlin 定义接口回调的一些疑问
回答 2
对称协程有哪些使用场景
回答 1