stateIn()
转变为热流StateFlow
public fun <T> Flow<T>.stateIn(
scope: CoroutineScope,
started: SharingStarted,
initialValue: T
): StateFlow<T> {
val config = configureSharing(1)
val state = MutableStateFlow(initialValue)
val job = scope.launchSharing(config.context, config.upstream, state, started, initialValue)
return ReadonlyStateFlow(state, job)
}
stateIn()
将冷流转换为热流StateFlow()
,这个流有几个特点:
一般可以用作替代LiveData,直接使用热流作为ViewModel
中可观察的数据源,LiveData
能实现的它都能实现,不能实现的它也都能实现。
stateIn()
转变为热流SharedFlow
public fun <T> Flow<T>.shareIn(
scope: CoroutineScope,
started: SharingStarted,
replay: Int = 0
): SharedFlow<T> {
val config = configureSharing(replay)
val shared = MutableSharedFlow<T>(
replay = replay,
extraBufferCapacity = config.extraBufferCapacity,
onBufferOverflow = config.onBufferOverflow
)
@Suppress("UNCHECKED_CAST")
val job = scope.launchSharing(config.context, config.upstream, shared, started, NO_VALUE as T)
return ReadonlySharedFlow(shared, job)
}
这个就是将冷流flow转换为SharedFlow
,上面的热流StateFlow
实现了SharedFlow
,它主要有以下几个特点:
两种冷流都需要传递一个SharingStarted类型的参数,这个参数有三种类型:Eagerly、Lazily、WhileSubscribed决定热流的启动模式,这里主要介绍WhileSubscribed:
public fun WhileSubscribed(
stopTimeoutMillis: Long = 0,
replayExpirationMillis: Long = Long.MAX_VALUE
): SharingStarted =
StartedWhileSubscribed(stopTimeoutMillis, replayExpirationMillis)
举个应用场景,当应用横竖屏切换时,订阅者就会被取消,但是没必要去停止流执行或者清理缓存,因为横竖屏过后很快就会重建重新显示,这样能更快的刷新界面数据。
retryWhen{}
public fun <T> Flow<T>.retryWhen(predicate: suspend FlowCollector<T>.(cause: Throwable, attempt: Long) -> Boolean): Flow<T> =
flow {
var attempt = 0L
var shallRetry: Boolean
do {
shallRetry = false
val cause = catchImpl(this)
if (cause != null) {
if (predicate(cause, attempt)) {
shallRetry = true
attempt++
} else {
throw cause
}
}
} while (shallRetry)
}
这个方法也很有用,出现异常时进行重试,并决定是否重试还是弹出提示信息,比如当我们进行网络请求时,请求失败就可以使用这个方法,一方面在retryWhen{}
方法中记录错误信息并通知下游流,一方面选择是否进行网络重试。
比如下面这个例子:
fun test2() {
GlobalScope.launch {
flow {
emit("${10 / 随机数}")
}
.retryWhen { cause, attempt ->
if (cause is ArithmeticException && attempt < 3) {
emit("retry")
true
} else {
false
}
}.collect {
println("jja: $it")
}
}
}
当上面的随机数出现0是就会触发ArithmeticException异常,这样retryWhen{}就能捕获并可以尝试重试,随机一个非0且能被整除的数,并且限制了重试次数为3次以为。
关于flow常见api系列文章陆陆续续写了五篇了,暂时就告一段落,基本上常用的都介绍了一遍,希望能够给大家带来帮助。
阅读量:747
点赞量:0
收藏量:0