使用 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(ActivityFragment):

vm.state
        .flowWithLifecycle(lifecycle)
        .onEach { state ->
            // handle all states
            if (state is Dump) {
                val data = state.data
                // use data
            }
    }.launchIn(lifecycleScope)

如果您不喜欢使用 MVVM 架构的方法,您可以在 UI class(ActivityFragment), 我不推荐:

listenPort().flowWithLifecycle(lifecycle)
        .onEach { data ->
            // use data
        }.launchIn(lifecycleScope)