使用协程更新UI异步调用 [英] Update UI async call with coroutines

查看:895
本文介绍了使用协程更新UI异步调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须使用对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:


  1. 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>:

    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屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆