我现有的Android代码使用AsyncTask
从虚拟COM连续轮询数据端口,并通过覆盖onProgressUpdate()
函数将数据转储到UI线程。如下所示:
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
中的串行端口上侦听,无论您使用某种侦听器还是无限循环,但我猜使用Flow
和MVVM
方法可以实现相同的结果。它看起来像下面这样:
在Repository类中:
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
}
InViewModel
:
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
In Ui(Activity
orFragment
):
vm.state
.flowWithLifecycle(lifecycle)
.onEach { state ->
// handle all states
if (state is Dump) {
val data = state.data
// use data
}
}.launchIn(lifecycleScope)
如果你不喜欢使用MVVM
架构的方法,你可以在UI类(Activity
或Fragment
)中完成所有这些,我不建议:
listenPort().flowWithLifecycle(lifecycle)
.onEach { data ->
// use data
}.launchIn(lifecycleScope)