使用 Coroutine 进行持续的数据轮询和转储到 UI
Using Coroutine for continuous data polling and dumping to UI
我现有的 Android 代码使用 AsyncTask
从 虚拟 COM 端口连续轮询数据,并通过重写将数据转储到 UI 线程onProgressUpdate()
函数。类似于以下内容:
open class ComActivity(deviceID:Int, listener: OnComRxUpdateUI) : AsyncTask<..., ..., ...>(){
...
override fun doInBackground(...) {
... //keep listening on serial port and transfer byte to buffer when available
}
override fun onProgressUpdate(...){
... //dump to ui
}
}
上面的代码工作正常(除了一些内存泄漏警告)。
时不时地,我看到 Coroutine
被提升用于执行并发和异步操作,我发现不得不尝试用协程替换 AsyncTask
。 OTOH,我没有完全掌握 Coroutines
替代 AsyncTask
的工作原理。所以我的问题是 Coroutine
是否是我用例的 可行 替代品(UI 上的连续数据轮询和转储)。任何好的高级(或伪)示例
欢迎在那里演示此用例。
很难假设您在 AsyncTask
中是如何在串行端口上监听的,无论您是使用某种监听器还是无限循环,但我想使用 [=24 可以达到相同的结果=] 和 MVVM
方法。它将类似于以下内容:
在存储库中 class:
fun listenPort(): Flow<String> = flow {
// keep listening on serial port, use emit() function to emit data
while (true) {
val data = listen()
emit(data)
}
}
suspend fun listen() = withContext(Dispatchers.IO) {
// listening on serial port
}
在ViewModel
中:
private val _state = MutableStateFlow<State>(Loading)
val state = _state
init {
repository.listenPort()
.onEach { data ->
_state.value = Dump(data)
}.launchIn(viewModelScope)
}
州:
sealed interface State
object Loading : State
data class Dump(val data: ...) : State
在Ui(Activity
或Fragment
):
vm.state
.flowWithLifecycle(lifecycle)
.onEach { state ->
// handle all states
if (state is Dump) {
val data = state.data
// use data
}
}.launchIn(lifecycleScope)
如果您不喜欢使用 MVVM
架构的方法,您可以在 UI class(Activity
或 Fragment
), 我不推荐:
listenPort().flowWithLifecycle(lifecycle)
.onEach { data ->
// use data
}.launchIn(lifecycleScope)
我现有的 Android 代码使用 AsyncTask
从 虚拟 COM 端口连续轮询数据,并通过重写将数据转储到 UI 线程onProgressUpdate()
函数。类似于以下内容:
open class ComActivity(deviceID:Int, listener: OnComRxUpdateUI) : AsyncTask<..., ..., ...>(){
...
override fun doInBackground(...) {
... //keep listening on serial port and transfer byte to buffer when available
}
override fun onProgressUpdate(...){
... //dump to ui
}
}
上面的代码工作正常(除了一些内存泄漏警告)。
时不时地,我看到 Coroutine
被提升用于执行并发和异步操作,我发现不得不尝试用协程替换 AsyncTask
。 OTOH,我没有完全掌握 Coroutines
替代 AsyncTask
的工作原理。所以我的问题是 Coroutine
是否是我用例的 可行 替代品(UI 上的连续数据轮询和转储)。任何好的高级(或伪)示例
欢迎在那里演示此用例。
很难假设您在 AsyncTask
中是如何在串行端口上监听的,无论您是使用某种监听器还是无限循环,但我想使用 [=24 可以达到相同的结果=] 和 MVVM
方法。它将类似于以下内容:
在存储库中 class:
fun listenPort(): Flow<String> = flow {
// keep listening on serial port, use emit() function to emit data
while (true) {
val data = listen()
emit(data)
}
}
suspend fun listen() = withContext(Dispatchers.IO) {
// listening on serial port
}
在ViewModel
中:
private val _state = MutableStateFlow<State>(Loading)
val state = _state
init {
repository.listenPort()
.onEach { data ->
_state.value = Dump(data)
}.launchIn(viewModelScope)
}
州:
sealed interface State
object Loading : State
data class Dump(val data: ...) : State
在Ui(Activity
或Fragment
):
vm.state
.flowWithLifecycle(lifecycle)
.onEach { state ->
// handle all states
if (state is Dump) {
val data = state.data
// use data
}
}.launchIn(lifecycleScope)
如果您不喜欢使用 MVVM
架构的方法,您可以在 UI class(Activity
或 Fragment
), 我不推荐:
listenPort().flowWithLifecycle(lifecycle)
.onEach { data ->
// use data
}.launchIn(lifecycleScope)