※ この記事は 2023/08/14 時点の情報を元に作成しています。
Android アプリで DB 操作を行うために、Room というライブラリを利用しました。
以下の公式を参考に取り組んだのですが、一筋縄ではいかなかったので、遭遇したエラーと解消方法について本記事に記録しておきます。
Room を使用してローカル データベースにデータを保存する | セットアップ
環境
- Android Studio Flamingo | 2022.2.1 Patch 2
- macOS 13.4.1
- compileSdk = targetSdk = 34
結論
build.gradle (Project :...)
に追記する内容は、以下のとおりです。
plugins {
...
id 'com.google.devtools.ksp' version '1.9.0-1.0.13' apply false
}
build.gradle (Module :app)
に追記する内容は、以下のとおりです。
plugins {
...
id 'kotlin-android'
id 'com.google.devtools.ksp'
}
...
dependencies {
...
def room_version = "2.5.2"
implementation "androidx.room:room-runtime:$room_version"
ksp "androidx.room:room-compiler:$room_version"
implementation "androidx.room:room-rxjava2:$room_version"
implementation "androidx.room:room-rxjava3:$room_version"
implementation "androidx.room:room-guava:$room_version"
testImplementation "androidx.room:room-testing:$room_version"
implementation "androidx.room:room-paging:$room_version"
}
やったことと遭遇したエラー
Android も Kotolin も初めての状態だったので、何も考えず公式のコードをコピペしました。
その時に遭遇したエラーがこちらです。
A problem occurred evaluating project ':app'.
> Could not find method kapt() for arguments [androidx.room:room-compiler:2.5.2] on object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.
モジュールが足りなさそうなことはエラーメッセージからわかりましたが、どう対処すればいいかはエラーメッセージに書いてありません。
ググった結果、build.gradle (Module :app)
に以下を追加しました。
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'kotlin-android' //追加
id 'kotlin-kapt' //追加
}
同様のエラーがksp()
に対しても、発生。
ググった結果、build.gradle (Module :app)
に以下を追加しました。
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'kotlin-android' //追加
id 'kotlin-kapt' //追加
id 'com.google.devtools.ksp' //更に追加
}
この時、build.gradle (Project :...)
にもcom.google.devtools.ksp
を追加しています。
そして発生したエラーがこちら。
警告:Schema export directory is not provided to the annotation processor so we cannot export the schema. You can either provide `room.schemaLocation` annotation processor argument OR set exportSchema to false.
ググって、一番簡単そうなexportSchema = false
を指定する方法を採用しました。
@Database(entities = [User::class], version = 1, exportSchema = false)
abstract class AppDatabase : RoomDatabase() {
そして発生したエラーがこちら。
エラー: クラス ...AppDatabase_Implが重複しています
Clean Project しても build ディレクトリ配下を削除しても解消せず。
散々ググった結果、kapt と ksp の両方を指定しているために、それぞれでクラスを自動生成して重複が発生する自体となった模様。
kapt の問題点を解消したのが ksp とのことで、kapt に関する記載を削除しました。
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'kotlin-android' //追加
// id 'kotlin-kapt' //削除
id 'com.google.devtools.ksp' //更に追加
}
...
dependencies {
...
def room_version = "2.5.2"
implementation "androidx.room:room-runtime:$room_version"
// annotationProcessor("androidx.room:room-compiler:$room_version") //削除
// kapt("androidx.room:room-compiler:$room_version") //削除
ksp "androidx.room:room-compiler:$room_version"
調査の過程で、kotlin でアノテーションを使用するために ksp が必要だったことが判明しました。
そのため、アノテーション関連のエラーメッセージの対応として追加していたexportSchema = false
も削除しました。
結果、公式から変更した箇所は、build.gradle (Module :app)
の内容だけになりました。
plugins {
...
id 'kotlin-android' //追加
id 'com.google.devtools.ksp' //追加
}
...
dependencies {
...
def room_version = "2.5.2"
implementation "androidx.room:room-runtime:$room_version"
// annotationProcessor("androidx.room:room-compiler:$room_version") //削除
// kapt("androidx.room:room-compiler:$room_version") //削除
ksp "androidx.room:room-compiler:$room_version"
implementation "androidx.room:room-rxjava2:$room_version"
implementation "androidx.room:room-rxjava3:$room_version"
implementation "androidx.room:room-guava:$room_version"
testImplementation "androidx.room:room-testing:$room_version"
implementation "androidx.room:room-paging:$room_version"
}
やっぱり何も理解しないでコピペすると、ハマりますね。