【发布时间】:2020-01-04 23:42:25
【问题描述】:
我在 kotlin 的 viewModel 的 init 中启动协程。 协程在循环中侦听数据,一切正常,但正如标题所暗示的那样,我无法取消该协程(或者 viewmodel 可能没有调用清除),因为 socked 保持连接。
// viewmodel
init {
viewModelScope.launch {
connector()
}
}
override fun onCleared() {
viewModelScope.cancel()
super.onCleared()
}
suspend fun connector() = withContext(Dispatchers.IO){
//val socket : Socket
try {
// connect socket
// listen in loop
} catch (Exception e){//whocares}
已经尝试在活动的背压时调用finish()(也尝试了一个片段)
【问题讨论】:
-
您的循环是否在检查协程是否被取消?取消在协程中是合作的。
-
@CommonsWare 我如何检查?尝试使用 'while (coroutineContext.isActive)' ,但无济于事,oncleared IS 被调用
-
协程取消是合作的。您需要检查循环内的
isActive,或者如果套接字阻塞线程并且协程无法到达下一个循环,则直接杀死套接字。 -
isActive应该可以工作,假设您实际上正在检查它,而您认为自己是。如果您在 I/O 上无限期地阻塞,您将不会在这些阻塞期间进行检查。您可能会查看Korio,它似乎具有协程友好的 TCP 套接字 I/O。 -
尝试杀死套接字,它到达了 catch 块,但是当重新启动活动时,它仍然卡在 catch 块中(协程仍然存在)。尝试在 catch 块中调用 [coroutineContext.]cancel,仍然活着,唯一能杀死它的是当我强制停止(或从 android studio 再次点击运行)时。这是我必须说的一个持久协程。
标签: android kotlin mvvm kotlin-coroutines android-viewmodel