Я хотел бы реализовать 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
, содержащего ссылку TextWatcher?
Я предполагаю, что мне не нужно беспокоиться об этом, основываясь на этом посте, но я хотел быть уверенным.