Kotlin协程不下载数据

时间:2018-12-01 11:30:13

标签: android kotlin kotlinx.coroutines

我在Android项目中使用Kotlin协同体。我正在尝试下载一些数据并在textview中显示。

以下是我的代码

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中添加了Internet许可,并且该网址也可以正常工作。

1 个答案:

答案 0 :(得分:2)

尝试一下:

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不应在协程中使用。它旨在将常规的阻塞代码桥接到以挂起方式编写的库中,以用于主要功能和测试中。

第二:

  

Coroutines are always related to some local scope in your application,这是寿命有限的实体,like a UI element

这就是Activity实现CoroutineScope的原因。老实说,更合适的地方是ViewModelPresenter,但是我在代码中看不到任何东西...

第三,在定义后立即使用asyncawait是毫无意义的。只需使用withContext