一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第5天,点击查看活动详情。
前言
随着官方的例子也在Activity里使用Flow(配上repeatOnLifecycle),LiveData也许会被StateFlow和SharedFlow替代了。那么到底Flow是怎样实现的呢?
扒一扒源代码,原来没有特别复杂。现在让我们从零开始自己写一个看看,顺便加深一下理解。
基本型
先设想一个简单的场景:定义一个函数(之后可以在别处调用)
fun main() {
val live: () -> Unit = {
print("吃")
print("睡")
}
live()
live()
}
将会输出:
吃
睡
加强版1
加一个(String) -> Unit类型的函数作为参数。我们可以在live内部调用这个函数,并给它定义一个名字emit。
fun main() {
val live: ((String) -> Unit) -> Unit = { emit ->
emit("吃")
emit("睡")
}
live { print(it) }
live { print(it) }
}
输出:
吃
睡
加强版2
下面定义一个接口FlowCollector:
fun interface FlowController {
fun emit(value: String)
}
// 更新如下
fun main() {
val live: (FlowCollector) -> Unit = {
it.emit("吃")
it.emit("睡")
}
live { print(it) }
live { print(it) }
}
输出同上。
it.emit(...) 看起来有点麻烦,能不能简化一下呢?
加强版3
fun interface FlowController {
fun emit(value: String)
}
// 把FlowCollector设为Receiver
fun main() {
val live: FlowCollector.() -> Unit = {
emit("吃")
emit("睡")
}
live { print(it) } // 吃
live { print(it) } // 睡
}
官方文档没有详细介绍Receiver的概念,感兴趣的同学可以自行搜索。。
再尝试把live的调用交给一个实例:
加强版4
interface Flow {
fun collect(collector: FlowCollector)
}
fun interface FlowController {
fun emit(value: String)
}
fun main() {
val live: FlowCollector.() -> Unit = {
emit("吃")
emit("睡")
}
val flow: Flow = object : Flow {
override fun collect(collector: FlowCollector) {
collector.live()
}
}
flow.collect { print(it) } // 吃
flow.collect { print(it) } // 睡
}
把生成实例的代码抽象出来:
加强版5
interface Flow {
fun collect(collector: FlowCollector)
}
fun interface FlowController {
fun emit(value: String)
}
fun flow(builder: FlowCollector.() -> Unit) = object : Flow {
override fun collect(collector: FlowCollector) {
collector.builder()
}
}
fun main() {
val live: Flow = flow {
emit("吃")
emit("睡")
}
live.collect { print(it) } // 吃
live.collect { print(it) } // 睡
}
注意到上面的FlowController接收的是String类型,可以继续抽象化:
interface Flow<T> {
fun collect(collector: FlowCollector<T>)
}
fun interface FlowController<T> {
fun emit(value: T)
}
fun <T> flow(builder: FlowCollector<T>.() -> Unit) = object : Flow<T> {
override fun collect(collector: FlowCollector<T>) {
collector.builder()
}
}
fun main() {
val live: Flow<String> = flow {
emit("吃")
emit("睡")
}
live.collect { print(it) } // 吃
live.collect { print(it) } // 睡
}
是不是已经和平时看到的Flow差不多了?再加把力,把异步支持也添上:
完整版
interface Flow<T> {
suspend fun collect(collector: FlowCollector<T>)
}
fun interface FlowController<T> {
suspend fun emit(value: T)
}
fun <T> flow(builder: FlowCollector<T>.() -> Unit) = object : Flow<T> {
override suspend fun collect(collector: FlowCollector<T>) {
collector.builder()
}
}
suspend fun main() {
val live: Flow<String> = flow {
emit("吃")
emit("睡")
}
live.collect { print(it) } // 吃
live.collect { print(it) } // 睡
}
回头翻翻源代码,几乎一致。其实知道思路之后实现也并不复杂,不过难就难在想到这种做法。