Kotlin Flow实现线程切换
flowOn方法实现线程切换
private fun flowOn() {
lifecycleScope.launch {//主线程
simpleFlowOn()
.flowOn(Dispatchers.IO)//子线程执行,耗时操作
.onStart {//最先开始
LogUtils.d("Thread is ${Thread.currentThread().name} onStart")
}
.onEach {
LogUtils.d("Thread is ${Thread.currentThread().name} onEach")
}
.catch { exception ->//异常接收
LogUtils.d("Thread is ${Thread.currentThread().name} exception $exception")
}
.onCompletion {//整个流完成
LogUtils.d("Thread is ${Thread.currentThread().name} onCompletion")
}
.collect {//数据接收
LogUtils.d("Thread is ${Thread.currentThread().name} collect $it")
}
}
}
//实现一个流,每秒发送一个数据
private fun simpleFlowOn(): Flow<Int> = flow {
for (i in 1..3) {
delay(1000)
LogUtils.d("Thread is ${Thread.currentThread().name} Emitting $i")
// if (i == 3) throw IllegalStateException("状态错误")
emit(i)
}
}
Log结果如下
//在主线程开始onStart
D/FlowFragment: Thread is main onStart
//发送在子线程
D/FlowFragment: Thread is DefaultDispatcher-worker-1 Emitting 1
D/FlowFragment: Thread is main onEach
//接收在主线程
D/Collect: Thread is main collect 1
D/FlowFragment: Thread is DefaultDispatcher-worker-1 Emitting 2
D/FlowFragment: Thread is main onEach
D/Collect: Thread is main collect 2
D/FlowFragment: Thread is DefaultDispatcher-worker-1 Emitting 3
D/FlowFragment: Thread is main onEach
D/Collect: Thread is main collect 3
//最后完成在主线程
D/FlowFragment: Thread is main onCompletion
注意:flowOn方法一般跟在flow耗时流后面,不然可能会造成其他方法也在子线程
看下面的方法,将flowOn放在onStart、onEach后面
private fun flowOn() {
lifecycleScope.launch {
simpleFlowOn()
.onStart {
LogUtils.d("Thread is ${Thread.currentThread().name} onStart")
}
.onEach {
LogUtils.d("Thread is ${Thread.currentThread().name} onEach")
}
.flowOn(Dispatchers.IO)
.catch { exception ->
LogUtils.d("Thread is ${Thread.currentThread().name} exception $exception")
}
.onCompletion {
LogUtils.d("Thread is ${Thread.currentThread().name} onCompletion")
}
.collect {
LogUtils.d("Thread is ${Thread.currentThread().name} collect $it")
}
}
}
打印如下,onStart,onEach方法执行都在子线程了:
//onStart,onEach方法执行都在子线程了
D/FlowFragment: Thread is DefaultDispatcher-worker-1 onStart
D/FlowFragment: Thread is DefaultDispatcher-worker-1 Emitting 1
D/FlowFragment: Thread is DefaultDispatcher-worker-1 onEach
D/Collect: Thread is main collect 1
D/FlowFragment: Thread is DefaultDispatcher-worker-1 Emitting 2
D/FlowFragment: Thread is DefaultDispatcher-worker-1 onEach
D/Collect: Thread is main collect 2
D/FlowFragment: Thread is DefaultDispatcher-worker-1 Emitting 3
D/FlowFragment: Thread is DefaultDispatcher-worker-1 onEach
D/Collect: Thread is main collect 3
D/FlowFragment: Thread is main onCompletion