【问题标题】:Kotlin Coroutine not waiting for the network result to returnKotlin 协程不等待网络结果返回
【发布时间】:2021-01-27 16:07:16
【问题描述】:

我正在尝试从 Kotlin 中的服务器获取一些数据,我希望在这些数据上做一些进一步的处理,比如向用户显示它。但是执行不是等待/阻塞结果返回,而是继续执行。

代码如下:

class UserLand : AppCompatActivity() {

class SyncViewModel(): ViewModel() {
        suspend fun startingSync(accesstoken: String): String {
            var response = ""
            viewModelScope.launch(Dispatchers.IO) {
                val reqParam = "token=$accesstoken"
                val mURL = URL("<-- server end point here -->")

                with(mURL.openConnection() as HttpURLConnection) {
                    // optional default is GET
                    requestMethod = "POST"

                    val wr = OutputStreamWriter(outputStream);
                    wr.write(reqParam);
                    wr.flush();

                    println("2 : $url")
                    println("3 : $responseCode")

                    BufferedReader(InputStreamReader(inputStream)).use {

                        var inputLine = it.readLine()
                        while (inputLine != null) {
                            response += inputLine
                            inputLine = it.readLine()
                        }
                        Log.d("4: ","Response : $response")
                    }
                }
            }
            Log.d("5", response)
            return response
        }
    }

 fun syncWithServer(view: View) {           
        val accesstoken = "johndoe"
        var response = ""
        if (accesstoken != null) {
            Log.d("----->", "1")
            runBlocking {
                response = SyncViewModel().startingSync(accesstoken)                
                Log.d("----->", "6")
            }
        }
        // 
        Log.d("Final result: 7:---------> ", response)

    }

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

我通过单击屏幕上的按钮呼叫syncWithServer()。此后,syncWithServer() 将在函数startingSync() 的单独线程上启动网络请求。现在我的目标日志的执行顺序如下:

1->2->3->4->5->6->7(根据日志和打印消息)。最后,在 log(7) 处,我将从服务器获得我想要进一步处理的响应。但实际执行结果如下:

1->6->2->3->4。注意 5 和 7 没有登录到 android logcats。我认为执行线程没有等待网络请求结果返回,因此没有达到理想的执行步骤。

我刚刚开始使用 kotlin 中的协同程序。我知道我遗漏了一些东西,但究竟是什么?

【问题讨论】:

    标签: android kotlin kotlin-coroutines


    【解决方案1】:

    viewModelScope.launch(Dispatchers.IO) 在您的代码中创建并行工作,您有 2 个变体来修复它:

    1 - 而不是viewModelScope.launch(Dispatchers.IO) 使用withContenxt(Dispatchers.IO) 只会改变dispathers

    2 - 使用 viewModelScope.async(Dispatchers.IO) 代替 viewModelScope.launch(Dispatchers.IO) 并通过调用此块的 .await() 结尾来等待结果

    【讨论】:

    • 我尝试了选项 1,它奏效了。谢谢你。你能解释一下为什么withContenxt(Dispatchers.IO) 有效而viewModelScope.launch(Dispatchers.IO) 无效吗?另外,这两者有什么区别,什么时候应该使用withContext()viewModelScope.launch()
    • withContenxt当前协程的执行跳转到一个IO线程。 launch 启动另一个协程。
    猜你喜欢
    • 2021-05-29
    • 2021-05-13
    • 2017-06-02
    • 2022-01-18
    • 1970-01-01
    • 2020-02-10
    • 2017-02-03
    • 2019-10-20
    • 1970-01-01
    相关资源
    最近更新 更多