-2

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?

Sebastien
  • 3,583
  • 4
  • 43
  • 82

1 Answers1

3

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.

Mark
  • 9,604
  • 5
  • 36
  • 64