谁能解释为什么这些 "Inappropriate blocking method call" 警告会从我的代码中弹出?

Can anyone explain why these "Inappropriate blocking method call" warnings pop up from my code?

我在 Kotlin 中编写了这段代码,以使用协程下载一些 API 信息来下载数据。但是,代码显示了很多警告,将消息声明为“不适当的阻塞方法调用”。

代码如下:

class DownloadInfoClass {
    private lateinit var url: URL
    private lateinit var httpURLConnection: HttpURLConnection
    private lateinit var result: String
    private lateinit var inputStream: InputStream
    private lateinit var inputStreamReader: InputStreamReader
    private var dataMap: MutableMap<String, Any> = mutableMapOf()

    private fun downloadMethod(urls: String){
        CoroutineScope(IO).launch {
            try {
                url = URL(urls)
                httpURLConnection = url.openConnection() as HttpURLConnection
                inputStream = httpURLConnection.inputStream
                inputStreamReader = InputStreamReader(inputStream)

                var data: Int = inputStreamReader.read()
                while (data != -1){
                    val current: Char = data.toChar()
                    result += current
                    data = inputStreamReader.read()
                }
            }

            catch (e: Exception){
                e.printStackTrace()
            }
        }
        Log.i("Result: ", result)
    }
}

出现此问题的具体区域是:

  1. URL(urls)
  2. openConnection()
  3. read()

谁能帮我理解为什么会这样?我通读了 Kotlin 文档,但无法理解。另外,你能告诉我如何解决这个问题吗?

要消除警告,请尝试使用 DownloadInfoClass 中的下一个代码:

private fun downloadMethod(urls: String) = CoroutineScope(Main).launch {
    url = URL(urls)
    val result = download() // suspends a coroutines launched using Main Context
    Log.i("Result: ", result)
}


private suspend fun download() = withContext(IO) { // download on background thread
    try {
        httpURLConnection = url.openConnection() as HttpURLConnection
        inputStream = httpURLConnection.inputStream
        inputStreamReader = InputStreamReader(inputStream)

        var data: Int = inputStreamReader.read()
        while (data != -1) {
            val current: Char = data.toChar()
            result += current
            data = inputStreamReader.read()
        }
        result // return result if there are no Exceptions
    } catch (e: Exception) {
        e.printStackTrace()
    }
    "" // return empty String if there is an Exception
}

问题是,协程被构建为仅 suspend 而不会阻塞线程。这意味着,多个协程可以 运行 在同一个线程上。当使用阻塞方法时,它们会阻塞整个线程并且可能会阻止其他协程 运行ning。所以,这样做通常是不好的做法。

由于您显然需要调用这些方法,因此请使用尝试为每个协程创建一个新线程的调度程序,例如 Dispatchers.IO(专为这些操作而设计,请参阅 documentation) .为此,只需用 withContext.

包装阻塞调用
withContext(Dispatchers.IO) { 
   // your blocking calls 
}

希望能帮到你!