database - studio - Biblioteca de persistencias de Android Room y Kotlin
room library android (6)
Estoy tratando de escribir una aplicación simple usando Kotlin y Room Persistance Library . Seguí el tutorial en el codelab de Android Persistance.
Aquí está mi clase
AppDatabase
en 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
}
}
}
Pero cuando traté de ejecutar la aplicación, se bloquea de inmediato. Aquí está el registro de bloqueo:
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)
Parece que la clase AppDatabase_Impl no se generó automáticamente. Verifiqué la aplicación original de Java descargada de codelab y descubrí que AppDatabase_Impl se generó automáticamente.
Versión de Kotlin: 1.1.2-3 Versión de la sala: 1.0.0-alpha1
¿Hay alguien experimentado con esto?
Editar: Usar kapt resuelve mi problema. En mi caso, tengo que reemplazar annotationProcessor con kapt.
Casi me rindo. pero después de hacer lo que dharmin007 dijo, también tuve que limpiar el proyecto. eso lo hizo funcionar. He notado que cada vez que agregas kapt a gradle, DEBES limpiar el proyecto después de sincronizar gradle.
Cualquier persona interesada en usar Kotlin con Room and Data Binding puede ver este proyecto de ejemplo https://github.com/entrpn/kotlin-room-databinding
En mi caso, en build.gradle, cuando tienes "annotationProcessor" necesitas duplicar con "kapt" y funciona.
compile "android.arch.persistence.room:runtime:$room_version"
annotationProcessor "android.arch.persistence.room:compiler:$room_version"
kapt "android.arch.persistence.room:compiler:$room_version"
No sé si mi respuesta es necesaria. Sé que algunas de las respuestas anteriores ya incluyeron esto en sus respuestas, pero agregaron otras cosas.
SOLO AGREGAR
apply plugin: ''kotlin-kapt''
Por lo general, en el proyecto
build.gradle
defino las versiones de dependencias:
ext {
buildToolsVersion = ''25.0.2''
supportLibVersion = ''25.3.1''
espressoVersion = ''2.2.2''
archRoomVersion = ''1.0.0-alpha1''
}
así que en la aplicación
build.gradle
las dependencias se ven así:
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''
}
Ahora puede definir las entidades Daos y la base de datos en Kotlin.
Base de datos:
@Database(entities = arrayOf(User::class), version = 1)
abstract class Database : RoomDatabase() {
abstract fun userDao(): UserDao
}
Entidad:
@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: consulta con parámetros. Kotlin cambia el nombre de los parámetros, por lo que la consulta SQL para recuperar todos los correos electrónicos que pertenecen a un usuario a través del ID de usuario es:
@Query("SELECT * FROM email "
+ "INNER JOIN user ON user.id = email.userId "
+ "WHERE user.id = :arg0")
fun getEmailsForUser(userId: Int): List<Email>
Pruebe estos pasos
Paso 1.
Establezca la
room_version
en el archivo
project.gradle
buildscript {
ext.kotlin_version = ''1.1.51''
ext.room_version = ''1.0.0-alpha9-1''
...
Paso 2.
Aplique el
kotlin-kapt
en el archivo
app.gradle
, y esto resolvió mi problema.
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"
...
Paso 3.
Agregue la dependencia
kapt
en el archivo
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"
...
}