我想实现一个DebounceTextWatcher。我打算使用actor
来消耗文本更改并在指定的时间间隔内反跳,然后将事件转发给外部使用者。代码如下:
class DebounceTextWatcher(
delayMs: Long = DebounceTextWatcher.DEFAULT_TIMER_DELAY_MS,
handler: (text: String) -> Unit
) : TextWatcher {
private val channel = GlobalScope.actor<String> {
debounce(delayMs).consumeEach(handler)
}
override fun afterTextChanged(s: Editable?) {
channel.offer(s?.toString().orEmpty())
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
companion object {
const val DEFAULT_TIMER_DELAY_MS = 600L
}
}
fun <T> ReceiveChannel<T>.debounce(timeMs: Long): ReceiveChannel<T> = GlobalScope.produce {
var value = receive()
whileSelect {
onTimeout(timeMs) {
send(value)
value = receive()
true
}
onReceive {
value = it
true
}
}
}
我的担忧是
GlobalScope
的正确使用吗?还是应该将CoroutineContext
或CoroutineScope
作为依赖项传递?close()
/ actor
的生命周期结束时,我是否需要担心以任何方式调用Activity
或终止Fragment
? / li>
我的假设是,根据this的帖子,我不必担心此事,但我想确定一下。
答案 0 :(得分:2)
通道本身不会保留任何资源,但是您的处理程序可能会保留。您要冒这样的事件顺序:
在类似的情况下,我有很多虚假的崩溃。我不停地插一个洞,在某些设备和某些特殊情况下,该应用仍然崩溃。仅当我实现“主作业”模式时,它才停止。后来,科特林实施了这种模式。