Я пытаюсь заполнить recyclerview
данными из Интернета, которые я хочу получить асинхронно.
У меня есть функция loadData()
, которая называется onCreateView()
, которая сначала делает видимым индикатор загрузки, затем вызывает функцию приостановки загрузки данных и затем пытается уведомить адаптер представления об обновлении.
Но в этот момент я получаю следующее исключение:
android.view.ViewRootImpl $ CalledFromWrongThreadException: только исходный поток, создавший иерархию представлений, может касаться его представлений.
, что удивило меня, так как мое понимание состояло в том, что только моя функция get_top_books()
была вызвана в другом потоке, и ранее, когда я показывал индикатор загрузки, я, очевидно, был в правом потоке.
Так почему возникает это исключение во время выполнения?
Мой код:
class DiscoverFragment: Fragment() {
lateinit var loadingIndicator: TextView
lateinit var viewAdapter: ViewAdapter
var books = Books(arrayOf<String>("no books"), arrayOf<String>("no books"), arrayOf<String>("no books"))
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val viewFrame = layoutInflater?.inflate(R.layout.fragment_discover, container, false)
val viewManager = GridLayoutManager(viewFrame!!.context, 2)
viewAdapter = ViewAdapter(books)
loadingIndicator = viewFrame.findViewById<TextView>(R.id.loading_indicator)
val pxSpacing = (viewFrame.context.resources.displayMetrics.density * 8f + .5f).toInt()
val recyclerView = viewFrame.findViewById<RecyclerView>(R.id.recycler).apply {
setHasFixedSize(true)
layoutManager = viewManager
adapter = viewAdapter
addItemDecoration(RecyclerViewDecorationSpacer(pxSpacing, 2))
}
loadData()
return viewFrame
}
fun loadData() = CoroutineScope(Dispatchers.Default).launch {
loadingIndicator.visibility = View.VISIBLE
val task = async(Dispatchers.IO) {
get_top_books()
}
books = task.await()
viewAdapter.notifyDataSetChanged()
loadingIndicator.visibility = View.INVISIBLE
}
}