使用协程更新UI异步调用 [英] Update UI async call with coroutines
问题描述
我必须使用对Room数据库的异步调用来更新UI,但是当我收到此错误时:android.view.ViewRootImpl $ CalledFromWrongThreadException:只有创建视图层次结构的原始线程才能触摸
I've got to update the UI with an async call to the Room Database, but when I do I've got this error : android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
//收藏夹Presenter.kt
// FavoritesPresenter.kt
GlobalScope.launch {
favoritesView.showFavorites(ProductProvider.getAllProducts() as ArrayList<Product>)
}
// ProductProvider.kt
// ProductProvider.kt
fun getAllProducts() : MutableList<Product> {
return dao.getAllProducts()
}
// ProductDao.kt
// ProductDao.kt
@Query("SELECT * FROM product")
fun getAllProducts(): MutableList<Product>
我需要通过ProductProvider更新UI,因为我将对所有实体使用我需要一个可靠的解决方案。
What I need is to update my UI though my ProductProvider, as I'll use for all my entities I need a reliable solution.
推荐答案
房间2.1 (当前为Alpha版)添加了对 Kotlin协程。您可以执行以下操作:
Room 2.1 (currently in alpha) adds support for Kotlin coroutines. You can do the following:
-
在
ProductDao
和ProductProvider
作为挂起:
// ProductDao.kt
@Query("SELECT * FROM product")
suspend fun getAllProducts(): List<Product>
// ProductProvider.kt
suspend fun getAllProducts(): List<Product> = dao.getAllProducts()
在 FavoritesPresenter
:
class FavoritesPresenter {
private var favoritesView: FavoritesView? = null
private val provider: ProductProvider = ...// initialize it somehow
private var job: Job = Job()
private val scope = CoroutineScope(job + Dispatchers.Main)
fun getProducts() {
scope.launch {
favoritesView?.showFavorites(provider.getAllProducts())
}
}
fun attachView(view: FavoritesView) {
this.favoritesView = view
}
fun detachView() {
job.cancel() // cancel the job when Activity or Fragment is destroyed
favoritesView = null
}
interface FavoritesView {
fun showFavorites(products: List<Product>)
}
}
使用 FavoritesPresenter $ c $
活动
或片段
中的c>:
class MainActivity : AppCompatActivity(), FavoritesPresenter.FavoritesView {
lateinit var presenter: FavoritesPresenter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// ...
presenter = FavoritesPresenter()
presenter.attachView(this)
presenter.getProducts()
}
override fun onDestroy() {
presenter.detachView()
super.onDestroy()
}
override fun showFavorites(products: List<Product>) {
// use products to update UI
}
}
要使用 Dispatchers.Main 导入:
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1'
这篇关于使用协程更新UI异步调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!