web-dev-qa-db-ja.com

Android Room PersistencesライブラリとKotlin

Kotlinと Room Persistance Library を使用して簡単なアプリを作成しようとしています。 Android Persistenceコードラボで チュートリアル に従いました。

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を使用すると問題が解決します。私の場合、annotationProcessorをkaptに置き換える必要があります。

53
Thanh Pham

通常、プロジェクト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'
}

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:パラメーター付きのクエリ。 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>
50

私の場合、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"
38
Lyofen

これらの手順を試してください

ステップ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。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"
...
}
10
dharmin007

ルームとデータバインディングでKotlinを使用することに興味がある人は誰でもこのサンプルプロジェクトを見ることができます https://github.com/entrpn/kotlin-room-databinding

4
Juan Acevedo

私はほとんどあきらめました。しかし、dharmin007が言ったことを実行した後、私はcleanプロジェクトもしなければならなかった。それが機能しました。 kaptをgradleに追加するたびに、gradleを同期した後にプロジェクトをクリーンアップする必要があることに気付きました。

1
j2emanue

私の答えに必要があるかどうかはわかりませんが、上記の答えのいくつかはすでにこれを回答に含めていましたが、彼らは他のものを追加しました

apply plugin: 'kotlin-kapt'のみを追加

1
Armstring