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())
                }
            }
        }
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章