首页 文章

Android Room Persistences库和Kotlin

提问于
浏览
51

我正在尝试使用Kotlin和Room Persistance Library编写一个简单的应用程序 . 我在Android Persistance codelab中关注the tutorial .

这是我在Kotlin的 AppDatabase 课程:

@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类没有自动生成 . 我检查了从codelab下载的原始java应用程序,发现AppDatabase_Impl是自动生成的 .

Kotlin版本:1.1.2-3房间版本:1.0.0-alpha1

有没有人经历过这个?

Edit: 使用kapt解决了我的问题 . 在我的情况下,我必须用kapt替换annotationProcessor .

5 回答

  • 8

    通常在项目 build.gradle 中我定义了依赖项版本:

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

    所以在app 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'
    }
    

    现在,您可以在Kotlin中定义实体Daos和数据库 .

    数据库:

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

    实体:

    @Entity(tableName = "user")
    class User {
        @PrimaryKey(autoGenerate = true)
        var id: Int = 0
        var name: String = ""
    }
    

    道:

    @Dao
    interface UserDao {
        @Query("SELECT * FROM user")
        fun getAll(): List<User>
    
        @Insert
        fun insertAll(vararg users: User)
    
        @Delete
        fun delete(user: User)
    }
    

    NB: Query with parameters. Kotlin重命名params,因此通过userId检索属于用户的所有电子邮件的SQL查询是:

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

    在我的情况下,在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"
    
  • 1

    尝试这些步骤

    Step 1.project.gradle 文件中设置 room_version

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

    Step 2.app.gradle 文件中应用 kotlin-kapt 插件,这解决了我的问题 .

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

    Step 3.app.gradle 文件中添加 kapt 依赖项

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

    任何对使用带有房间和数据绑定的Kotlin感兴趣的人都可以看到这个示例项目https://github.com/entrpn/kotlin-room-databinding

  • 4

    我几乎放弃了 . 但在做了什么dharmin007之后我也不得不对这个项目进行了讨论 . 这使它工作 . 我注意到,每当你将kapt添加到gradle时,你必须在同步gradle之后清理项目 .

相关问题