android - “不适当的阻塞方法调用” - 如何在 Android Studio 上处理此警告
问题描述
我已经编写了这个代码片段来将图像文件从 firebase 存储下载到本地存储。
contentResolver.openOutputStream(uri)?.use { ops -> // *
Firebase.storage.getReferenceFromUrl(model.mediaUrl).stream.await().stream.use { ips ->
val buffer = ByteArray(1024)
while (true) {
val bytes = ips.read(buffer) // *
if (bytes == -1)
break
ops.write(buffer, 0, bytes) // *
}
}
}
在标记的行中,android studio 向我Inappropriate blocking method call
发出警告,突出显示 openOutputStream()、read() 和 write() 函数。我已经运行了几次代码并且它运行正常。整个代码片段在一个挂起函数中,从 IO CoroutineScope 调用。
有人请告诉我此警告的实际原因和解决方案。
编辑此代码在以下上下文中调用。
fun someFunc() {
lifecycleScope.launch(IO) {
val uri = getUri(model)
...
}
...
}
...
suspend fun getUri(model: Message): Uri {
... // Retrive the image file using mediastore.
if ( imageNotFound ) return downloadImage(model)
else return foundUri
}
suspend fun downloadImage(model: Message): Uri {
... // Create contentvalues for new image.
val uri = contentResolver.insert(collectionUri, values)!!
// Above mentioned code snippet is here.
return uri
}
解决方案
一个正确组合的挂起函数永远不会阻塞。它不应该依赖于从特定的调度程序调用,而是应该在适当的调度程序中显式地包装阻塞代码。
因此,调用阻塞代码的挂起函数部分应该包含在withContext(Dispatchers.IO){}
. 然后调用它的协程甚至不需要指定调度程序。这使得调用函数和更新 UI 非常方便,lifecycleScope
无需担心调度程序。
例子:
suspend fun foo(file: File) {
val lines: List<String> = withContext(Dispatchers.iO) {
file.readLines()
}
println("The file has ${lines.size} lines.")
}
推荐阅读
- vue.js - 属性或方法“posts”未在实例上定义,但在渲染期间引用
- python-3.x - 将 XML 解析为 Pandas Dataframe、Python 3.8、ElementTree
- javascript - 如何从从 javascript 发送到烧瓶的发布请求中获取返回值
- .net - 如何序列化/反序列化保留其元数据的数据集,从 .NET Framework 4.7.2 中的客户端应用程序发送到 Core 3.1 中的 gRPC 服务
- python - 追加数据框问题
- c# - 如果玩家在空白处单击统一 2d,则播放
- docker - 如何调试 docker-compose up 失败?
- python - 带有 print() 的 Python 多处理不起作用
- c# - 如何将 MainWindow 上的自定义属性放入 UserControl(来自 UserControl 库/DLL)?
- amazon-s3 - 如何使用 IAM 角色而不是访问密钥和秘密密钥将 Amazon S3 存储桶访问到 Kubernetes pod?