我目前正在尝试更多利用kotlin协程。但是我面临一个问题:在这些协程中使用moshi或okhttp时,我会收到警告:
“不合适的阻止方法调用”
解决这些问题的最佳方法是什么?我真的不想不合适;-)
答案 0 :(得分:27)
调用挂起函数@Throws(IOException::class)
(Kotlin 1.3.61)时,也会收到此警告。不知道这是否是故意的。无论如何,您可以通过删除该注释或将其更改为Exception
类来禁止显示此警告。
答案 1 :(得分:26)
可能会发生异常,这就是它显示此警告的原因。使用runCatching{}
。它捕获从块函数执行中抛出的任何 Throwable 异常并将其封装为失败。
例如:
CoroutineScope(Dispatchers.IO).launch {
runCatching{
makeHttpRequest(URL(downloadLocation))
}
}
答案 2 :(得分:17)
包装在其他上下文中使用 {{1将“不适当的阻止方法调用” 代码 }} 。
也就是说(例如):
如果您正在执行读/写阻止方法调用:
withContext
如果您正在执行阻止网络请求(使用翻新):
val objects = withContext(Dispatchers.IO) { dao.getAll() }
或者如果您正在执行CPU密集型阻止任务:
val response = withContext(Dispatchers.IO) { call.execute() }
这将挂起当前的协程,然后在不同的线程(来自val sortedUsers = withContext(Dispatchers.Default) { users.sortByName() }
或Dispatchers.IO
池)上执行“不适当的阻塞调用” >不阻止您的协程在其上执行的线程。
答案 3 :(得分:2)
如果您确实像某些答案所建议的那样选择抑制,请使用
@Suppress("BlockingMethodInNonBlockingContext")
答案 4 :(得分:1)
警告是关于无法正确暂停阻止当前线程和协程的方法。这样,您将失去协程的所有好处,并再次将每个线程降级为一项工作。
每种情况应以不同的方式处理。对于可挂起的http呼叫,您可以使用ktor http client。但是有时您的案例没有库,因此您可以编写自己的解决方案或忽略此警告。
答案 5 :(得分:0)
我正在使用Android Studio 4.1,当我使用Moshi
或操纵File
时会显示警告。即使我确定自己在做什么,也无法将代码包装在withContext
中。
我最近发现,将发出警告的小代码移入没有suspend
之类的fun action() {...}
的标准方法中,可以消除警告。这有点难看,因为它隐藏了警告。
答案 6 :(得分:-1)
我使用调度程序作为启动参数:
GlobalScope.launch(Dispatchers.IO) {
// Do background work
// Back to main thread
launch(Dispatchers.Main) {
Toast.makeText(context, "SUCCESS!", Toast.LENGTH_LONG)
.show()
}
}