持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第21天,点击查看活动详情
前言
对于kotlin的flow看过我前面的一些文章应该对其有一定的了解,今天我们一起来看看flow创建的七种方式。
常用方法
flowOf()
flowOf()从给定的一组项目创建一个流实例。基本上,它是一个静态流构建器,其中包含要发出的预定义项。
val demoFlow = flowOf("第一个数据", "第二个数据", "第三个数据")
demoFlow.collect {
println("$it")
}
asFlow()
asFlow()是一个扩展函数。您可以将对应的非流数据通过asFlow()转换为 Flow。
// 作为集合转换
val demoList = listOf("第一个数据", "第二个数据", "第三个数据")
val demoFlow = demoList.asFlow()
demoFlow.collect {
println("$it")
}
flow{}
从给定的可暂停块创建冷流实例,我们可以在其中手动发出值。当我们开始收集它时,它只会发出一次。
fun demo() = flow {
emit("需要发射的数据")
delay(1000) // 发射每隔一秒
}.collect{
println("$it")
}
热流
MutableStateFlow
可变状态持有者流向其收集器发出当前值和初始值。MutableStateFlow 是一个热流。有了StateFlow数据就是一种状态。
class DemoViewModel:ViewModel(){
// 使用热流 MutableStateFlow
private val _uiState = MutableStateFlow<UiState>(UiState.Success(""))
val uiState : StateFlow<UiState> = _uiState
private val demoList = listOf("第一个数据", "第二个数据", "第三个数据")
fun demoFuction() {
viewModelScope.launch {
_uiState.tryEmit(UiState.Loading)
demoList.asFlow().collect { str ->
_uiState.tryEmit(UiState.Success(str))
}
}
}
// 定义UI状态行为
sealed class UiState{
object Loading : UiState()
data class Success(str:String) : UiState()
}
}
MutableSharedFlow
可变共享流,在其所有收集器之间共享所有发出的值。
class DemoViewModel : ViewModel() {
val sharedFlow = MutableSharedFlow<Int>(
replay= 1, // 当有新得流需要收集时,它可以接受几个历史数据
extraBufferCapacity = 3, // 除去replay,MutableSharedFlow还缓存多少数据
onBufferOverflow = BufferOverflow.DROP_OLDEST // 有三种缓存策略 1. 丢掉最新值 2. 丢掉最旧值 3.等待
)
// 发射数据
sharedFlow.tryEmit(1)
sharedFlow.tryEmit(2)
sharedFlow.tryEmit(3)
// 新的收集
val job1 = sharedFlow.onEach {
Log.e("Job1","Collected $it")
}.launchIn(this)
// 新的收集
val job2 = sharedFlow.onEach {
Log.e("Job2","Collected $it")
}.launchIn(this)
delay(1000)
job1.cancel()
delay(1000)
job2.cancel()
// 结果
// job1打印 Collected2
// job2打印 Collected2
}
其他方式
ChannelFlow
ChannelFlow 在单独的协程中生成值,而无需等待接收者完成对发射项目的处理。而正常流程按顺序工作,emit()暂停直到消费者完成最新项目的工作。
val demoScope = CoroutineScope(Dispatchers.IO)
val demoFlow = channelFlow {
println("发送 : 1")
send("1")
println("发送 : 2")
send("2")
}
demoScope.launch {
demoFlow.collect {
println("收集 $it")
delay(5000)
}
}
// 输出顺序:
// 发送 : 1
// 发送 : 2
// 收集 : 1
// 5秒之后打印:收集 : 2
CallbackFlow
创建一个冷流实例,将异步回调转换为流,如按钮单击。我们不能使用简单的Flow,因为emit()它是挂起函数,callbackFlow允许从与函数不同CoroutineContext的send函数或与函数的协程外部发出值trySend。
fun demoCallBackFlow(): Flow<Boolean> = callbackFlow {
val callback = object : DemoCallback() {
override fun onSuccess() {
trySend(true)
}
override fun onFailre() {
trySend(false)
}
}
demoRegisterFunction(callback)
awaitClose {
// 回调结束时执行
demoUnRegisterFunction(callback)
}
}
emptyFlow
创建一个空的流
fun demoFunction(nullAbleStr: String?): Flow<String> {
return if (nullAbleStr.isNullOrEmpty()) {
emptyFlow<String>()
} else {
flow {
emit("不为空返回值")
}
}
}
}