我目前正在尝试更多地利用kotlin协程。但我面临一个问题:当在这些协程中使用moshi或okhttp时,我得到一个警告:
“不恰当的阻塞方法调用”
解决这些问题的最好方法是什么?我真的不想不合适;-)
我目前正在尝试更多地利用kotlin协程。但我面临一个问题:当在这些协程中使用moshi或okhttp时,我得到一个警告:
“不恰当的阻塞方法调用”
解决这些问题的最好方法是什么?我真的不想不合适;-)
当前回答
它看起来像在kotlin.runCatching()中封装调用解决了警告,但不确定为什么…因为正如之前关于runCatching的回答所说,这不是由于抛出异常,因为即使try{} catch也不能解决问题,可能是一些错误检测问题… 我现在使用了下面的方法……
val result = kotlin.runCatching {
OldJavaLib.blockingCallThatThrowsAnException()
}
if (result.isSuccess) {
print("success is on your side")
} else {
print("one failure is never the end")
}
其他回答
我使用dispatchers作为启动参数:
GlobalScope.launch(Dispatchers.IO) {
// Do background work
// Back to main thread
launch(Dispatchers.Main) {
Toast.makeText(context, "SUCCESS!", Toast.LENGTH_LONG)
.show()
}
}
如果你选择像一些答案建议的那样压抑,那就使用
@Suppress(“BlockingMethodInNonBlockingContext”)
它看起来像在kotlin.runCatching()中封装调用解决了警告,但不确定为什么…因为正如之前关于runCatching的回答所说,这不是由于抛出异常,因为即使try{} catch也不能解决问题,可能是一些错误检测问题… 我现在使用了下面的方法……
val result = kotlin.runCatching {
OldJavaLib.blockingCallThatThrowsAnException()
}
if (result.isSuccess) {
print("success is on your side")
} else {
print("one failure is never the end")
}
使用withContext将“不适当的阻塞方法调用”代码包装到另一个上下文中。
也就是说(例如):
如果你正在执行一个读/写阻塞方法调用:
val objects = withContext(Dispatchers.IO) { dao.getAll() }
如果您正在执行阻塞网络请求(使用Retrofit):
val response = withContext(Dispatchers.IO) { call.execute() }
或者如果你正在执行一个CPU密集型的阻塞任务:
val sortedUsers = withContext(Dispatchers.Default) { users.sortByName() }
这将挂起当前的协程,然后在不同的线程上执行“不适当的阻塞调用”(来自Dispatchers)。IO或Dispatchers。(默认池),因此不会阻塞协程正在执行的线程。
我今天遇到了同样的问题,下面的解决方案对我来说很有效。希望能有所帮助!
CoroutineScope(Dispatchers.IO).launch {
val call = client.newCall(request)
call.enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
print("Internet access, 4G, Wifi, DNS, etc failed")
}
override fun onResponse(call: Call, response: Response) {
if(response.isSuccessful) {
print("Server accepted!")
} else {
print("Server failed!")
}
}
})
}
请记住,这个回调函数只被使用一次。你不能在其他线程中使用它。