androidkotlinokhttpappauth

NetworkOnMainThreadException when trying to run okhttp response code on UI thread


In my Android app, I'm using AppAuth to authenticate the user with an OpenID connect endpoint, so I'm doing a bunch of asynchronous calls and when the last one returns, I'm using okhttp to get the final result and I want to show it in the UI of my activity, something like this:

authService.performTokenRequest(
    authResponse.createTokenExchangeRequest()
) { tokenResponse: TokenResponse?, tokenException: AuthorizationException? ->
    if (tokenResponse != null) {                         
        authState.performActionWithFreshTokens(authService) { accessToken, _, ex ->
            if (accessToken != null) {
                val url = ...
                val request = ...
                http.newCall(request).enqueue(object: Callback {
                    override fun onFailure(call: Call?, e: IOException?) {...}
                    override fun onResponse(call: Call?, response: Response?) {
                        if (response != null) {
                            this@MainActivity.runOnUiThread {
                                textView.text = response.body()!!.string()
                            }
                        }
                    }
                })
            }
        }
    }
}

But then on the line when I try to update my text view, I get the following exception:

android.os.NetworkOnMainThreadException

And when I try to remove the runOnUiThread, I'm getting another exception that says: "Only the original thread that created a view hierarchy can touch its views"

I don't get it. What should I do?


Solution

  • This should work:

    override fun onResponse(call: Call?, response: Response?) {                           
        val body = response?.body()?.string()
        this@MainActivity.runOnUiThread { textView.text = body }              
    }
    

    You shouldn't access the response on the UI thread as it is considered a IO operation.