Kotlin过早地回来了

时间:2017-10-25 13:45:26

标签: android asynchronous kotlin

我正在尝试使用Kotlin开始Android开发。我正在尝试做的部分工作是从我的登录活动发送HTTP请求,并从响应中采取适当的操作。我正在使用Fuel

点击“登录”按钮后,我正在拨打以下fun

private fun disableInput() {
    username_input.isEnabled = false
    password_input.isEnabled = false
    sign_in_button.isEnabled = false
    login_progress.visibility = View.VISIBLE
}

这很好用。然后我发出我的HTTP请求:

"http://my.login.url.com".httpPost()
    .header("Content-Type" to "application/json")
    .body(json, Charsets.UTF_8)
    .response(AuthorizationSuccess.Deserializer()) { _, response, result ->
        val (auth, error) = result

        if (error != null || auth == null) {
            Snackbar.make(view, "Error", 0).show()
            enableInput()
        } else {
           // Handle the response
        }
    }

问题是,当我收到错误时,我似乎无法重新启用UI。显示Snack并调用enableInput

private fun enableInput() {
    username_input.isEnabled = true
    password_input.isEnabled = true
    sign_in_button.isEnabled = true
    login_progress.visibility = View.GONE
}

但是,它只会击中第一行(username_input.isEnabled = true)并且不会再进一步​​。它确实启用了用户名输入,因此我知道分配正在成功,但我无法弄清楚为什么它不会继续启用UI的其余部分。

我怀疑它与我从异步操作中调用它的事实有关,但我还没有找到任何其他方法来实现它。

我应该采用一种特殊的方式来呼叫enableInput,还是这种方法完全是错误的?

1 个答案:

答案 0 :(得分:2)

UI代码必须在Android的UI线程中运行。

disableInput函数运行以响应按钮单击,因此它已经在UI线程中,但是当您处理HTTP响应时,Fuel将在另一个线程中运行您的回调。

要更改回UI线程以更新UI组件,请使用View::post,如下所示:

private fun enableInput() {
    username_input.post {
        username_input.isEnabled = true
        password_input.isEnabled = true
        sign_in_button.isEnabled = true
        login_progress.visibility = View.GONE
    }    
}   

正如我在评论中所说,在Kotlin中,使用camelCase也是一种惯例,因此使用username_input代替usernameInput