错在了哪
我先把那篇文章中错误的代码贴上来:
// 错误代码🙅
binding.etSearch.doOnTextChanged { text, _, _, _ ->
searchFilter(text.toString())
}
private fun searchFilter(str:String){
flow { emit(str) }
.debounce(400)
.filter {
it.isNotEmpty()
}
.catch { LogUtils.d(it.message) }
.flowOn(Dispatchers.Default)
.onEach {
LogUtils.d(“输出:$it”)
binding.tvShow.text = it.toString()
}.flowOn(Dispatchers.Main)
.launchIn(lifecycleScope)
}
复制代码
仔细看上面的代码,你们自己想想错在了哪里?
文本输入框etSearch
每次文本的变化都会回掉searchFilter()
方法,而方法里面每次都去实例化了一个flow
,然后又使用了debounce()
限流,那么这个debounce()
限流的意义何在?毫无意义啊,对吧。因为每次都是新创建的flow
啊。
还不懂的话,那就看下面简化的代码:
// 文章错误代码🙅的简化
for (i in 0…100) {
// 模拟生成数据
flow {
emit(i)
}.debounce(500) // 这里是无效的 限流,因为 flow 的 emit 只执行了一次啊……
.collect {
println("----------------->>> $it")
}
}
复制代码
那么我们理想中的正确代码逻辑是这样的:
flow {
for (i in 0…100) {
// 模拟生成数据
emit(i)
}
}.debounce(500) // 这里是有效的 限流
.collect {
println("----------------->>> $it")
}
复制代码
好了,同学们可以再对比以上两段代码,for
循环就是我们模拟的输入数据,这个for
循环在里面和在外面是两个完全不一样的逻辑~不再多做解释了
正确的用法
你以为的正确写法
对于输入框的这类业务逻辑,单纯使用flow
是无法到达目的的,因为写不出来。有的小朋友要站起来高喊了,“怎么写不出来,你瞎说,我来写”,一顿操作写出了下面的代码:
// 小朋友写的错误代码🙅
flow {
editText.doAfterTextChanged { text ->
emit(text) // 这里是错误的,emit不可以写在内部类中
}
}.debounce(500)
.collect {
println("----------------->>> $it")
}
复制代码
错误的地方我写上了注释,emit
是一个suspend
挂起函数,是不可以写在内部类里的,代码直接编译不通过。
真正的正确写法
首先我提一个知识点,大家回忆一下。RxJava
中的流,是分为冷流和热流(即:cold Observable和 hot Observable)对吧。如果你说啥,流还分冷热?亲,那这里建议你炒个回锅肉呢。
在RxJava
的使用中,不注意区分冷热流,是导致RxJava
错用、滥用的原因之一!
这里我只用两句话简单解释冷热流,不展开讲RxJava
。
【附】相关架构及资料
资料领取
点击这里免费获取Android IOC架构设计等资料
免费获取Android IOC架构设计等资料](https://github.com/a120464/Android-P7/blob/master/Android%E5%BC%80%E5%8F%91%E4%B8%8D%E4%BC%9A%E8%BF%99%E4%BA%9B%EF%BC%9F%E5%A6%82%E4%BD%95%E9%9D%A2%E8%AF%95%E6%8B%BF%E9%AB%98%E8%96%AA%EF%BC%81.md)**