version情報 #
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-kapt' <<== 追加。kaptはソースコード生成する機能のよう
}
dependencies {
...
implementation("androidx.room:room-runtime:2.4.1")
implementation("androidx.room:room-ktx:2.4.1") <= corutine使うのに必要
annotationProcessor("androidx.room:room-compiler:2.4.1")
kapt("androidx.room:room-compiler:2.4.1")
implementation "androidx.compose.runtime:runtime-livedata:$compose_version" <= LiveDataをobserveAsState()するのに必要
...
}
https://developer.android.com/jetpack/androidx/releases/room
日本語のページだと古いことがある 英語で見るほうがよさそうです
LiveData #
LiveDataのobserveAsStateを使うには、gradleに以下を追加する
implementation "androidx.compose.runtime:runtime-livedata:$compose_version"
なお、observeAsState()はComposable関数のなかでしか使えない。
ViewModelのなかではLiveDataとして持っておいて、
Composeable関数のなかで、 val state = liveData.observeAsState()として値の変更を監視する
Flowの場合は #
Composableの中で.collectAsStateを使うとステートとして監視できる
Coroutineの使用 #
メインスレッドでQueryできるようにするには、Roomをつくるときに .allowMainThredQueries()を追加する。
val db = Room.databaseBuilder(
context,
KirokuDatabase::class.java, "database.db"
).allowMainThreadQueries().build()
insertなどはcorutineを使ってメインスレッド以外で実行するようにする。
コルーチンスコープを作ってDispatchers.IOとするとIO用のスレッドで動作する。
fun insert(kiroku: Kiroku) {
val scope = CoroutineScope(Dispatchers.IO)
scope.launch {
kirokuDao.insertAll(kiroku)
}
}
fun delete(kiroku: Kiroku) {
val scope = CoroutineScope(Dispatchers.IO)
scope.launch {
kirokuDao.delete(kiroku)
}
}
Repositoryでsuspendにしてもよい (Daoでsuspendでもよい)
suspend fun insert(kiroku: Kiroku): Int {
return withContext(Dispatchers.IO) {
val insertedId = kirokuDao.insert(kiroku)
insertedId.toInt()
}
}
これをviewModelスコープから
fun saveEdittingKiroku() {
viewModelScope.launch(Dispatchers.IO) {
val insertedID = Graph.repo.insert(kirokuEditting.value)
Log.d("saveEdittingKiroku", "editID:${kirokuEditting.value.id}, insertedID:$insertedID")
if (kirokuEditting.value.id == 0 && insertedID != 0) { // newly created
// copy images from 0 to insertedID
Graph.repo.moveImageDir(0, insertedID)
}
}
}
insertでrowIDを取得する #
返り値をLogにすると、insertした後で自動的に割り当てられたIDが取得できる。
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(kiroku: Kiroku): Long