简体   繁体   中英

Kotlin fun returning prematurely

I'm trying to get started with Android development using Kotlin. Part of what I'm trying to do is send an HTTP request from my login activity and take appropriate action from the response. I'm using Fuel for this.

When the "Sign in" button is tapped, I'm calling the following fun :

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

This works fine. I then make my HTTP request:

"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
        }
    }

The problem is that when I receive an error, I can't seem to re-enable the UI. The Snack is shown and enableInput is called:

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

However, it hits only the first line ( username_input.isEnabled = true ) and goes no further. It does enable the username input so I know the assignment is succeeding, but I can't figure out why it doesn't proceed to enable the rest of the UI.

I suspect it has something to do with the fact that I'm calling it from an asynchronous operation, but I haven't been able to find any other way to do it.

Is there a special way I ought to be calling enableInput , or is this completely the wrong way to go about it?

UI code must run in the UI Thread in Android.

The disableInput function runs in response to a button click, so it is already in the UI Thread, but when you handle the HTTP response, Fuel will run your callback in a different Thread.

To change back to the UI Thread to update your UI components, use View::post , something like this:

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

As I said in the comments, in Kotlin, it's also a convention to use camelCase, so instead of username_input , use usernameInput .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM