database Android Room Persistences 库和 Kotlin

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/44065371/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 08:05:45  来源:igfitidea点击:

Android Room Persistences library and Kotlin

databasekotlinkaptandroid-room

提问by Thanh Pham

I am trying to write a simple app using Kotlin and Room Persistance Library. I followed the tutorialin the Android Persistance codelab.

我正在尝试使用 Kotlin 和Room Persistance Library编写一个简单的应用程序。我遵循Android Persistance codelab 中的教程

Here is my AppDatabaseclass in Kotlin:

这是我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
        }
    }
}

But when I tried to run the app, it crashes immediately. Here is the crash log:

但是当我尝试运行该应用程序时,它立即崩溃。这是崩溃日志:

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.access0(ActivityThread.java:157)?
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1356)

It looks like the class AppDatabase_Impl wasn't autogenerated. I checked the original java app downloaded from codelab and found that AppDatabase_Impl was autogenerated.

看起来类 AppDatabase_Impl 不是自动生成的。我检查了从codelab下载的原始java应用程序,发现AppDatabase_Impl是自动生成的。

Kotlin version: 1.1.2-3 Room version: 1.0.0-alpha1

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

Is there anyone experienced with this?

有没有人有这方面的经验?

Edit:Using kapt solves my problem. In my case, I have to replace annotationProcessor with kapt.

编辑:使用 kapt 解决了我的问题。就我而言,我必须用 kapt 替换 annotationProcessor。

采纳答案by Nicola De Fiorenze

Usually in project build.gradleI define the dependencies versions:

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

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

so in app build.gradlethe dependencies look like:

所以在应用程序中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'
}

Now you can define Entities Daos and Database in Kotlin.

现在您可以在 Kotlin 中定义实体道和数据库。

Database:

数据库:

@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: Query with parameters.Kotlin renames params, so the SQL query to retrieve all the emails that belong at an user via the userId is:

注意:带参数的查询。Kotlin 重命名参数,因此通过 userId 检索属于用户的所有电子邮件的 SQL 查询是:

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

回答by Lyofen

In my case, in build.gradle, when you have "annotationProcessor" you need to duplicate with "kapt" and it works.

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

回答by dharmin007

Try out these steps

试试这些步骤

Step 1.Set the room_versionin the project.gradlefile

步骤 1.room_versionproject.gradle文件中设置

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

Step 2.Apply the kotlin-kaptplugin in the app.gradlefile, and this solved my issue.

步骤 2.kotlin-kaptapp.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"
...

Step 3.Add the kaptdependency in the app.gradlefile

步骤 3.kaptapp.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"
...
}

回答by Juan Acevedo

Anyone interested in using Kotlin with Room and Data Binding can see this sample project https://github.com/entrpn/kotlin-room-databinding

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

回答by j2emanue

i almost gave up. but after doing just what dharmin007 said i also had to cleanthe project. that made it work. I've noticed that whenever you add kapt to gradle you MUST clean the project after synching gradle.

我几乎放弃了。但是在按照 dharmin007 所说的去做之后,我还必须清理该项目。这使它起作用。我注意到,每当您将 kapt 添加到 gradle 时,您必须在同步 gradle 后清理项目。

回答by Mohammad Elsayed

I don't know if there is a necessity to my answer I know that some of the above answers already included this to their answers but they added other things

我不知道我的答案是否有必要我知道上面的一些答案已经包含在他们的答案中,但他们添加了其他内容

ONLY ADD apply plugin: 'kotlin-kapt'

只添加 apply plugin: 'kotlin-kapt'