△ Room 中對 Flow 的支持html
Jetpack Room 對協程的支持愈來愈豐富: Room 2.1 版本增長了對協程的支持,並加入了一次性 (one-shot) 的讀寫操做,Room 2.2 咱們經過 Flow 爲讀操做加入了可觀察性,當數據庫中的數據有變化時它能夠使您收到通知。android
△ Room 支持異步 query 操做git
假設咱們有一個記錄小狗信息的數據庫,它的 name 字段是主鍵 (primary key),因此在數據庫中不可能同時有兩個 name 字段相同的數據,也就是每隻小狗都是惟一的。github
@Entity data class Dog ( @PrimaryKey val name: String, val cuteness: Int, val barkingVolume: Int )
爲了從數據中獲取一個包含全部小狗信息的總表,咱們在 [DAO](https://developer.android.goo...
) 中編寫以下 query 語句:數據庫
@Query("SELECT * FROM Dog") fun getAllDogs(): List<Dog>
由於小狗的叫聲,也就是字段 barkingVolume 會隨着時間變化,而且咱們想確保 UI 展現的內容是最新的。所以咱們但願,當數據庫中的數據有變化時,能夠通知到咱們: 好比新增,刪除,或者是更新了數據。異步
爲了實現這個功能,咱們經過更新 query 操做返回一個 Flow 對象。google
@Query("SELECT * FROM Dog") fun getAllDogs(): Flow<List<Dog>>
就像這樣,每當數據庫中的數據有更新時,會從新派發存有小狗信息的總表。例如,假設咱們的數據庫中存有以下數據:spa
(Frida, 11, 3) (Bandit, 12, 5)
第一次調用 getAllDogs 時 Flow 派發的數據以下:code
[(Frida, 11, 3), (Bandit, 12, 5)]
若是小狗 Bandit 比較興奮,那它的叫聲也會變大,也就是字段 barkingVolume 更新爲 6: (Bandit,12,6),這時候 Flow 會從新派發最新數據,因此整個列表被更新爲:協程
[(Frida, 11, 3), (Bandit, 12, 6)]
如今咱們來看一下獲取單隻小狗詳細信息的操做,爲了可以實時地獲取小狗的最新數據,咱們返回 Flow:
@Query("SELECT * FROM Dog WHERE name = :name") fun getDog(name: String): Flow<Dog>
若是咱們調用 getDog("Frida"),Flow 會返回一個對象: (Frida, 11, 3)。
只要是數據庫中的任意一個數據有更新,不管是哪一行數據的更改,那就從新執行 query 操做並再次派發 Flow,所以當小狗 Frida 有更新時咱們會收到最新的數據。一樣道理,若是一個不相關的數據,好比小狗 Bandit 有更新時咱們的 Flow 也會被派發,並且會收到與以前相同的數據: (Frida, 11, 3)。
這是由於 SQLite 數據庫的內容更新通知功能是以表 (Table) 數據爲單位,而不是以行 (Row) 數據爲單位,所以只要是表中的數據有更新,它就觸發內容更新通知。Room 不知道表中有更新的數據是哪個,所以它會從新觸發 DAO 中定義的 query 操做。您能夠使用 Flow 的操做符,好比 distinctUntilChanged 來確保只有在當您關心的數據有更新時纔會收到通知。
@Dao abstract class DoggosDao { @Query("SELECT * FROM Dog WHERE name = :name") abstract fun getDog(name: String): Flow<Dog> fun getDogDistinctUntilChanged(name:String) = getDog(name).distinctUntilChanged() }
推薦您經過 Flow 進行可觀察的讀操做,以獲取數據庫中數據更新的通知!您能夠在您的整個應用中使用協程 (Coroutine) 和 Flow,並且還可以使用 Jetpack 庫中支持的其餘協程功能,好比: 生命週期感知型協程範圍 (lifecycle-aware coroutine scopes) 、掛起生命週期感知型協程 (suspend lifecycle-aware coroutines),也包括 Flow 轉 LiveData 的操做。
查看更多使用 Flow 的案例,可參考咱們以前發佈的一篇基於 Android 開發者峯會應用的最佳實踐 的文章。