Android 无法取消用viewModelScope启动的协同路由
我正在kotlin的viewModel的init内部启动协同程序。 协同路由侦听循环中的数据,一切正常,但作为标题,我无法取消该协同路由(或者可能viewmodel没有调用cleared),因为socked保持连接Android 无法取消用viewModelScope启动的协同路由,android,kotlin,mvvm,kotlin-coroutines,android-viewmodel,Android,Kotlin,Mvvm,Kotlin Coroutines,Android Viewmodel,我正在kotlin的viewModel的init内部启动协同程序。 协同路由侦听循环中的数据,一切正常,但作为标题,我无法取消该协同路由(或者可能viewmodel没有调用cleared),因为socked保持连接 // viewmodel init { viewModelScope.launch { connector() } } override fun onCleared() { viewModelScope.cancel() super.
// 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}
已尝试在活动的backpressed上调用finish()(也尝试了一个片段)这应该可以解决您的问题,将作业分配给一个变量,然后使用它来取消
var job : Job? = null
// viewmodel
init {
job = viewModelScope.launch {
connector()
}
}
override fun onCleared() {
job?.cancel()
super.onCleared()
}
suspend fun connector() = withContext(Dispatchers.IO){
//val socket : Socket
try {
// connect socket
// listen in loop
} ca
协同程序中的取消必须是合作的。i、 e您的代码应该检查协同程序状态。 在套接字连接中,应选中
isActive
或ensure reactive()
至少在继续之前调用任何回调时。
理想的解决方案是手动关闭套接字连接器,因为不能保证任何回调都会成功。将被调用。您也可以尝试使用
suspendCancelableCorroutine
循环是否检查是否取消了该Corroutine?取消在协同程序中是合作的。@Commonware如何检查?尝试使用“while(coroutineContext.isActive)”,没有帮助,但是,一旦Cleared被调用,例程取消是协作的。你需要在你的循环中检查isActive
,或者如果套接字阻塞了线程,那么直接杀死它,协同程序就不会到达下一个循环。isActive
应该可以工作,假设你真的在检查它的时候你认为是这样的。如果无限期地阻塞I/O,则在这些阻塞期间将不会进行检查。您可能会看到,它似乎具有对协同路由友好的TCP套接字I/O。尝试终止套接字时,它会到达catch块,但当重新启动活动时,它仍然卡在catch块内(协同路由仍处于活动状态)。尝试在catch块中调用[coroutineContext.]cancel,但仍处于活动状态,唯一杀死它的是当我强制停止(或从android studio再次点击run)时。我必须说,这是一个持久的协同路由。协同路由可以通过在作用域或作业上调用cancel()来实现