Kotlin协程不下载数据

Kotlin coroutines not downloading data

我在 Android 项目中使用 Kotlin 协程。我正在尝试下载一些数据并在文本视图中显示。

以下是我的代码

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        tv.setOnClickListener {
            downloadData()
        }
    }


    private fun downloadData() {

        runBlocking {
            pb_activity_main.visibility = View.VISIBLE
            var data = ""
            async {
                data = downloadDataBlocking()
            }.await()
            tv.text = data
            pb_activity_main.visibility = View.GONE

        }
    }


    private fun downloadDataBlocking(): String {
        val client = OkHttpClient()
        val request = Request.Builder().url("https://jsonplaceholder.typicode.com/posts").build()
        val response = client.newCall(request).execute()
        return response.body()?.string() ?: ""
    }
}

但是没有下载数据。我不知道为什么。

我已经在 Manifest 中包含了互联网许可,并且 url 也在工作。

试试这个:

class MainActivity : AppCompatActivity(), CoroutineScope {

    private val job = Job()
    override val coroutineContext = Dispatchers.Main + job

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        tv.setOnClickListener {
            downloadData()
        }
    }


    private fun downloadData() {
        launch {
            pb_activity_main.visibility = View.VISIBLE
            tv.text = withContext(Dispatchers.IO) { downloadDataBlocking() }
            pb_activity_main.visibility = View.GONE
        }
    }


    private fun downloadDataBlocking(): String {
        val client = OkHttpClient()
        val request = Request.Builder().url("https://jsonplaceholder.typicode.com/posts").build()
        val response = client.newCall(request).execute()
        return response.body()?.string() ?: ""
    }
}

首先:你应该永远不要在单元测试或其他特殊领域之外使用runBLocking

This function should not be used from coroutine. It is designed to bridge regular blocking code to libraries that are written in suspending style, to be used in main functions and in tests.

第二个:

Coroutines are always related to some local scope in your application, which is an entity with a limited life-time, like a UI element.

这就是 Activity 实施 CoroutineScope 的原因。老实说,更好的地方是 ViewModelPresenter,但我在代码中没有看到任何内容...

第三,在定义之后立即使用asyncawait是毫无意义的。那就用withContext吧。