〈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
で良さそう。