〈kotlin〉Room② 非同期DAO

Android studioでkotlinを使ってAndroidアプリ作成の勉強中。

データベースSQLiteを簡単に扱うことができるRoomの実装をまとめる。

前回の記事の続き。
<kotlin> Room - ゆるプログラミング日記

「クエリが UI をブロックしないように、Room はメインスレッドでのデータベース アクセスを許可していない」を解決したい。
そのためにDAOクエリを非同期にする必要がある。

1. suspend関数にする

DAO内のメソッドにsuspendキーワードをつけることで、コルーチンで使用するメソッドにする。
挿入、更新、削除などの書き込みや、その時点のデータベースの読み取りなど
1回で終了するワンショットクエリに使用する。

@Dao
interface UserDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertUsers(vararg users: User)

    @Update
    suspend fun updateUsers(vararg users: User)

    @Delete
    suspend fun deleteUsers(vararg users: User)

    @Query("SELECT * FROM user WHERE id = :id")
    suspend fun loadUserById(id: Int): User

    @Query("SELECT * from user WHERE region IN (:regions)")
    suspend fun loadUsersByRegion(regions: List<String>): List<User>
}

2. Flowを使用する

メソッドの戻り値をFlowにすることで、クエリは自動的にバックグラウンドで実行されるようになる。
(Flowはデータの変更を監視できるコルーチンのメソッド)
基になるデータベース テーブルが変更されるたびにデータベースからデータを読み取り、
その変更を反映するために新しい値を出力するオブザーバブルクエリで使用する。

@Dao
interface UserDao {
    @Query("SELECT * FROM user WHERE id = :id")
    fun loadUserById(id: Int): Flow<User>

    @Query("SELECT * from user ")
    fun loadUsers() : Flow<List<User>>
}

ViewModel内でLiveDataに変換して取得することもできる。

val allUsers : LiveData<List<User>> = UserDao.loadUsers().asLiveData()


DAO内のメソッドには

  • 1回処理を行うだけならsuspend
  • データの変更を監視し続けるなら戻り値Flow

で良さそう。



参考非同期 DAO クエリを作成する  |  Android デベロッパー  |  Android Developers