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?
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.