Android Room Persistences库和Kotlin
我正在尝试使用Kotlin和Room Persistance Library编写一个简单的应用程序。 我遵循Android Persistance codelab中的教程 。
这是我在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
有没有人经历过这个?
编辑:使用kapt解决我的问题。 在我的情况下,我必须用kapt替换annotationProcessor。
通常在项目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) }
注意:用参数查询。 Kotlin重命名params,所以SQL查询通过userId检索属于用户的所有电子邮件是:
@Query("SELECT * FROM email " + "INNER JOIN user ON user.id = email.userId " + "WHERE user.id = :arg0") fun getEmailsForUser(userId: Int): List<Email>
在我的情况下,在build.gralde中,当你有“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"
任何有兴趣使用房间和数据绑定Kotlin的人可以看到这个示例项目https://github.com/entrpn/kotlin-room-databinding
尝试这些步骤
第1步。在project.gradle
文件中设置room_version
buildscript { ext.kotlin_version = '1.1.51' ext.room_version = '1.0.0-alpha9-1' ...
第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" ...
第3步。在app.gradle
文件中添加kapt
依赖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" ... }