Updating Views asynchronously
After calling books = task.await()
you are outside UI thread. It is because you use CoroutineScope(Dispatchers.Default)
. Change it to Dispatchers.Main
:
fun loadData() = CoroutineScope(Dispatchers.Main).launch {
loadingIndicator.visibility = View.VISIBLE
val task = async(Dispatchers.IO) {
get_top_books()
}
books = task.await()
viewAdapter.notifyDataSetChanged()
loadingIndicator.visibility = View.INVISIBLE
}
After calling books = task.await()
you are outside UI thread. You should run all UI related code in the main thread. To do this you can use Dispatchers.Main
.
CoroutineScope(Dispatchers.Main).launch {
viewAdapter.notifyDataSetChanged()
loadingIndicator.visibility = View.INVISIBLE
}
Or using Handler
Handler(Looper.getMainLooper()).post {
viewAdapter.notifyDataSetChanged()
loadingIndicator.visibility = View.INVISIBLE
}
Or you can use Activty
instance to call runOnUiThread
method.
activity!!.runOnUiThread {
viewAdapter.notifyDataSetChanged()
loadingIndicator.visibility = View.INVISIBLE
}
Changing the Dispatchers.Default
to Dispatchers.Main
and upgrading my version of kotlinx-coroutines-android
to 1.1.1
did the trick.
Changing
val task = async(Dispatchers.IO) {
get_top_books()
}
books = task.await()
to
books = withContext(Dispatchers.IO) {
get_top_books()
}
is also a bit more elegant. Thanks to everyone who responded especially @DominicFischer who had the idea to check my dependencies.