Библиотека сохранности Android Room и Kotlin
Я пытаюсь написать простое приложение, используя Kotlin и Room Persistance Library. Я следовал за учебником в кодовой надписи Android Persistance.
Вот мой класс AppDatabase
в Kotlin:
@Database(entities = arrayOf(User::class), version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun userModel(): UserDao
companion object {
private var INSTANCE: AppDatabase? = null
@JvmStatic fun getInMemoryDatabase(context: Context): AppDatabase {
if (INSTANCE == null) {
INSTANCE = Room.inMemoryDatabaseBuilder(context.applicationContext, AppDatabase::class.java).allowMainThreadQueries().build()
}
return INSTANCE!!
}
@JvmStatic fun destroyInstance() {
INSTANCE = null
}
}
}
Но когда я попытался запустить приложение, оно сразу вылетает. Вот журнал сбоев:
Caused by: java.lang.RuntimeException: cannot find implementation for com.ttp.kotlin.kotlinsample.room.AppDatabase. AppDatabase_Impl does not exist
at android.arch.persistence.room.Room.getGeneratedImplementation(Room.java:90)
at android.arch.persistence.room.RoomDatabase$Builder.build(RoomDatabase.java:340)
at com.ttp.kotlin.kotlinsample.room.AppDatabase$Companion.getInMemoryDatabase(AppDatabase.kt:19)
at com.ttp.kotlin.kotlinsample.MainKotlinActivity.onCreate(MainKotlinActivity.kt:28)
at android.app.Activity.performCreate(Activity.java:6272)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1108)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2387)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2494)
at android.app.ActivityThread.access$900(ActivityThread.java:157)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1356)
Похоже, класс AppDatabase_Impl не был создан автоматически. Я проверил оригинальное Java-приложение, загруженное из codelab, и обнаружил, что AppDatabase_Impl создан автоматически.
Версия Kotlin: 1.1.2-3 Версия комнаты: 1.0.0-alpha1
Есть ли кто-нибудь опыт с этим?
Изменить: Использование капт решает мою проблему. В моем случае я должен заменить annotationProcessor на kapt.
Ответы
Ответ 1
Обычно в проекте build.gradle
я определяю версии зависимостей:
ext {
buildToolsVersion = '25.0.2'
supportLibVersion = '25.3.1'
espressoVersion = '2.2.2'
archRoomVersion = '1.0.0-alpha1'
}
поэтому в приложении build.gradle
зависимости выглядят следующим образом:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
compile "com.android.support:appcompat-v7:${rootProject.supportLibVersion}"
compile "android.arch.persistence.room:runtime:${rootProject.archRoomVersion}"
annotationProcessor "android.arch.persistence.room:compiler:${rootProject.archRoomVersion}"
kapt "android.arch.persistence.room:compiler:${rootProject.archRoomVersion}"
androidTestCompile("com.android.support.test.espresso:espresso-core:${rootProject.espressoVersion}", {
exclude group: 'com.android.support', module: 'support-annotations'
})
testCompile 'junit:junit:4.12'
}
Теперь вы можете определить Entities Daos и базу данных в Котлине.
База данных:
@Database(entities = arrayOf(User::class), version = 1)
abstract class Database : RoomDatabase() {
abstract fun userDao(): UserDao
}
Entity:
@Entity(tableName = "user")
class User {
@PrimaryKey(autoGenerate = true)
var id: Int = 0
var name: String = ""
}
Dao:
@Dao
interface UserDao {
@Query("SELECT * FROM user")
fun getAll(): List<User>
@Insert
fun insertAll(vararg users: User)
@Delete
fun delete(user: User)
}
NB: запрос с параметрами.
Kotlin переименовывает параметры, поэтому запрос SQL для извлечения всех писем, принадлежащих пользователю через userId, выглядит следующим образом:
@Query("SELECT * FROM email "
+ "INNER JOIN user ON user.id = email.userId "
+ "WHERE user.id = :arg0")
fun getEmailsForUser(userId: Int): List<Email>
Ответ 2
В моем случае, в build.gradle, когда у вас есть "annotationProcessor", вам нужно продублировать "kapt", и это работает.
compile "android.arch.persistence.room:runtime:$room_version"
annotationProcessor "android.arch.persistence.room:compiler:$room_version"
kapt "android.arch.persistence.room:compiler:$room_version"
Ответ 3
Попробуйте выполнить следующие шаги.
Шаг 1. Установите room_version
в файле project.gradle
buildscript {
ext.kotlin_version = '1.1.51'
ext.room_version = '1.0.0-alpha9-1'
...
Шаг 2. Примените плагин kotlin-kapt
в файле app.gradle
, и это решило мою проблему.
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
android {
compileSdkVersion 26
buildToolsVersion "26.0.1"
...
Шаг 3. Добавьте kapt
зависимость в файле app.gradle
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation "android.arch.persistence.room:runtime:$room_version"
annotationProcessor "android.arch.persistence.room:compiler:$room_version"
kapt "android.arch.persistence.room:compiler:$room_version"
...
}
Ответ 4
Любой, кто заинтересован в использовании Kotlin с функцией Room и Data Binding, может увидеть этот образец проекта https://github.com/entrpn/kotlin-room-databinding
Ответ 5
я почти сдался. но после всего, что сказал dharmin007, мне также пришлось очистить проект. это заставило это работать. Я заметил, что всякий раз, когда вы добавляете kapt в gradle, вы ДОЛЖНЫ очищать проект после синхронизации gradle.
Ответ 6
Я не знаю, есть ли необходимость в моем ответе, я знаю, что некоторые из вышеупомянутых ответов уже включили это в свои ответы, но они добавили другие вещи
ТОЛЬКО ДОБАВИТЬ apply plugin: 'kotlin-kapt'