kotlin: flow: 用launchIn指flow运行的线程
一,代码:
自定义线程
val myCustomDispatcher1 = newSingleThreadContext("MyCustomThread1")
调用
//处理按钮点击事件
binding.button1.setOnClickListener {
runBlocking {
val flow = flow {
//logX("Start")
emit(1)
logX("Emit: 1")
emit(2)
logX("Emit: 2")
emit(3)
logX("Emit: 3")
}
val scope = CoroutineScope(myCustomDispatcher1)
flow.flowOn(Dispatchers.IO)
.filter {
logX("Filter: $it")
it > 2
}
.onEach {
logX("onEach $it")
}
.launchIn(scope)
}
}
//处理按钮点击事件
binding.button2.setOnClickListener {
runBlocking {
val scope = CoroutineScope(myCustomDispatcher1)
val flow = flow {
//logX("Start")
emit(1)
logX("Emit: 1")
emit(2)
logX("Emit: 2")
emit(3)
logX("Emit: 3")
}
.flowOn(Dispatchers.IO)
.filter {
logX("Filter: $it")
it > 2
}
.onEach {
logX("onEach $it")
}
scope.launch { // 注意这里
flow.collect{
// logX("collect $it")
}
}
delay(100L)
}
}
launchIn(scope) 的功能: 把它上游的代码都分发到指定的线程当中。
launchIn 从严格意义来讲,应该算是一个下游的终止操作符,因为它本质上是调用了 collect()。
注意: 由于 Flow 当中直接使用 withContext 是很容易引发其他问题的,
因此,withContext 在 Flow 当中是不被推荐的
二,运行结果:
第一个按钮被点击:可以看到filter及其下游都是自定义的MyCustomThread1,
flowOn及以上都是DefaultDispatcher-worker-1
第二个按钮被点击:效果与1相同