53 votes

Bibliothèque Android Room Persistences et Kotlin

Je suis en train d'écrire une application simple à l'aide de Kotlin et Salle de Persistance de la Bibliothèque. J'ai suivi le tutoriel dans l'Android Persistance codelab.

Voici mon AppDatabase de la classe dans 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
        }
    }
}

Mais quand j'ai essayé d'exécuter l'application, il se bloque immédiatement. Voici le rapport de crash:

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)

Elle ressemble la classe AppDatabase_Impl n'était pas généré automatiquement. J'ai vérifié l'origine de java application téléchargée à partir de codelab et a constaté que AppDatabase_Impl a été généré automatiquement.

Kotlin version: 1.1.2-3 Salle de version: 1.0.0-alpha1

Quelqu'un est-il vécu cela?

Edit: À l'aide de kapt résout mon problème. Dans mon cas, je dois remplacer annotationProcessor avec kapt.

50voto

Nicola De Fiorenze Points 754

Habituellement, dans le projet de l' build.gradle - je définir les dépendances versions:

ext {
    buildToolsVersion = '25.0.2'
    supportLibVersion = '25.3.1'
    espressoVersion = '2.2.2'
    archRoomVersion = '1.0.0-alpha1'
}

donc dans app build.gradle les dépendances ressembler à:

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'
}

Maintenant, vous pouvez définir des Entités Daos et de la Base de données dans Kotlin.

Base de données:

@Database(entities = arrayOf(User::class), version = 1)
abstract class Database : RoomDatabase() {
    abstract fun userDao(): UserDao
}

Entité:

@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: Requête avec des paramètres. Kotlin renomme params, de sorte que la requête SQL pour récupérer tous les e-mails qui appartiennent à un utilisateur par l'intermédiaire de l'identifiant est:

@Query("SELECT * FROM email "
            + "INNER JOIN user ON user.id = email.userId "
            + "WHERE user.id = :arg0")
    fun getEmailsForUser(userId: Int): List<Email>

38voto

Lyofen Points 462

Dans mon cas, dans build.gradle, lorsque vous avez "annotationProcessor", vous devez dupliquer avec "kapt" et cela fonctionne.

 compile "android.arch.persistence.room:runtime:$room_version"
annotationProcessor "android.arch.persistence.room:compiler:$room_version"
kapt "android.arch.persistence.room:compiler:$room_version"
 

9voto

dharmin007 Points 634

Essayez ces étapes

Étape 1. Définissez les room_version dans le fichier project.gradle

 buildscript {
    ext.kotlin_version = '1.1.51'
    ext.room_version = '1.0.0-alpha9-1'
...
 

Étape 2. Appliquer le kotlin-kapt plug - in dans le app.gradle fichier, ce qui a résolu mon problème.

 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"
...
 

Étape 3. Ajoutez le kapt dépendance dans le app.gradle fichier

 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"
...
}
 

4voto

Juan Acevedo Points 1015

Toute personne intéressée à utiliser Kotlin avec Room and Data Binding peut voir cet exemple de projet https://github.com/entrpn/kotlin-room-databinding.

1voto

j2emanue Points 3456

j'ai failli abandonner. mais après avoir fait exactement ce que dharmin007 a dit, je devais également nettoyer le projet. cela a fonctionné. J'ai remarqué que chaque fois que vous ajoutez kapt à gradle, vous devez nettoyer le projet après avoir synchronisé gradle.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by: