lig*_*igi 172 kotlin okhttp moshi kotlin-coroutines
我目前正在尝试更多地利用 kotlin 协程。但我面临一个问题:在这些协程中使用 moshi 或 okhttp 时,我收到警告:
“不适当的阻塞方法调用”
解决这些问题的最佳方法是什么?我真的不想不合适;-)
Evg*_*kin 61
警告是关于阻塞当前线程和协程的方法无法正确挂起。这样,您将失去协程的所有好处并再次降级为每个线程一个作业。
每种情况都应以不同的方式处理。对于可挂起的 http调用,您可以使用ktor http client。但有时没有适合您的库,因此您可以编写自己的解决方案或忽略此警告。
编辑:withContext(Dispatchers.IO)或者一些自定义调度程序可以用来解决这个问题。感谢您的评论。
Mar*_*ark 54
在调用带有@Throws(IOException::class)(Kotlin 1.3.61)注释的挂起函数时,您也会收到此警告。不确定这是不是有意的。无论如何,您可以通过删除该注释或将其更改为Exception类来抑制此警告。
Sye*_*air 42
可能会发生异常,这就是它显示此警告的原因。使用runCatching{}. 它捕获从块函数执行中抛出的任何 Throwable 异常并将其封装为失败。
例如:
CoroutineScope(Dispatchers.IO).launch {
runCatching{
makeHttpRequest(URL(downloadLocation))
}
}
Run Code Online (Sandbox Code Playgroud)
Zul*_*fil 24
总结了“不适当的阻塞方法调用” 代码在另一种情况下使用withContext。
也就是说(例如):
如果您正在执行读/写阻塞方法调用:
val objects = withContext(Dispatchers.IO) { dao.getAll() }
Run Code Online (Sandbox Code Playgroud)
如果您正在执行阻塞网络请求(使用 Retrofit):
val response = withContext(Dispatchers.IO) { call.execute() }
Run Code Online (Sandbox Code Playgroud)
或者,如果您正在执行 CPU 密集型阻塞任务:
val sortedUsers = withContext(Dispatchers.Default) { users.sortByName() }
Run Code Online (Sandbox Code Playgroud)
这将挂起当前协程,然后在不同的线程(来自或池)上执行“不适当的阻塞调用”,从而不会阻塞您的协程正在执行的线程。Dispatchers.IODispatchers.Default
我使用的是 Android Studio 4.1,当我使用Moshi或操作File. withContext即使我确定自己在做什么,将代码包装在 a 中也无济于事。
我最近发现将警告的小代码移动到标准方法中而不是suspend像fun action() {...}可以消除警告。这很丑陋,因为它只是隐藏了警告。
| 归档时间: |
|
| 查看次数: |
52997 次 |
| 最近记录: |