'Inappropriate blocking method call' - How to handle this warning on Android Studio

我只是一个虾纸丫 提交于 2020-12-15 00:53:16

问题


I have written this code snippet to download image files from firebase storage to local storage.

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)   // *
        }
    }
}

In the marked lines, android studio is giving me Inappropriate blocking method call warning, highlighting openOutputStream(), read() and write() functions. I have ran the code few times and it has worked properly. This entire code snippet is inside a suspend function, called from an IO CoroutineScope.
Someone please tell me the actual cause and solutions for this warning.

Edit This code is called in the following context.

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
}

回答1:


A properly composed suspend function never blocks. It should not depend on being called from a specific dispatcher, but rather it should explicitly wrap blocking code in the appropriate dispatcher.

So the parts of your suspend function that call blocking code should be wrapped in withContext(Dispatchers.IO){}. Then the coroutine that calls it doesn't even need to specify a dispatcher. This makes it very convenient to use lifecycleScope to call functions and update UI and never worry about dispatchers.

Example:

suspend fun foo(file: File) {
    val lines: List<String> = withContext(Dispatchers.iO) {
        file.readLines()
    }
    println("The file has ${lines.size} lines.")
}


来源:https://stackoverflow.com/questions/65200617/inappropriate-blocking-method-call-how-to-handle-this-warning-on-android-stu

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!