Room数据库配合Flow监听数据变化

自版本 2.1.0 以来的重要变更

协程流:现在,@Query DAO 方法的返回值类型可以为 Flow<T>。如果查询中的观察表已失效,返回的流将重新发出一组新值。声明具有 Channel<T> 返回类型的 DAO 函数是错误的做法,Room 建议您使用 Flow,然后使用相邻函数将 Flow 转换为 Channel。b/130428884

在2.2.0版本开始,Room数据库增加了协程流的功能,简单解释来说就是,你可以监听数据库中数据的变化了,不用通过定时器或者利用activity的生命周期来刷新数据了

在使用协程流之前,你需要添加androidx.room:room-ktx

    //Room数据库: https://developer.android.google.cn/jetpack/androidx/releases/room
    def room_version = "2.4.0"
    implementation "androidx.room:room-runtime:$room_version"
    kapt "androidx.room:room-compiler:$room_version"
    implementation  "androidx.room:room-ktx:$room_version"

在使用的时候,只需要吧原来dao文件中对应方法的返回值使用Flow进行包裹就可以了,需要注意的是,在包裹Long Int这些类型时需要设置可空,否则在查不到数据时就会出现空指针异常

/**
     * 添加运动记录
     */
    @Insert
    fun addSportLog(sportLog: SportLog): Long

    /**
     * 查询所有运动记录
     */
    @Query("select * from t_sport_log order by create_time desc")
    fun getAllSportLog(): Flow<List<SportLog>>

    /**
     * 查询所有运动时长
     */
    @Query("select sum(sport_time) from t_sport_log")
    fun getAllSportTime(): Flow<Long?>

在调用的时候,按照以下方式进行调用就可以了,这样就实现了对数据库中数据的变化监听,不用手动刷新数据了,需要注意的是,你需要把这些调用设置一个作用域,然后才能使用,在使用时我发现,一个作用域只能调用一个协程流,暂时还没找到相关的说明,有知道的小伙伴可以在评论区留言讨论

override fun initData() {
        lifecycleScope.launch {
            val allSportTime = DbHelper.db.sportDao().getAllSportTime()
            allSportTime.collect { value ->
                runOnUiThread {
                    if (value == null) {
                        sport_time?.text = "${0}分钟"
                    } else {
                        sport_time?.text = "${value}分钟"
                    }
                }
            }
        }
        lifecycleScope.launch {
            val allSportLog = DbHelper.db.sportDao().getAllSportLog()
            allSportLog.collect { values ->
                runOnUiThread {
                    sportLogAdapter.setData(values.toMutableList())
                }
            }
        }
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章