Kotlin中的Room Persistence lib实现

我在kotlin中为我的数据库实现实现了Room persistence lib。

以下是我的EntityDaoDatabase类:

Food.kt

 @Entity class Food(@ColumnInfo(name = "food_name") var foodName: String, @ColumnInfo(name = "food_desc") var foodDesc: String, @ColumnInfo(name = "protein") var protein: Double, @ColumnInfo(name = "carbs") var carbs: Double, @ColumnInfo(name = "fat") var fat: Double) { @ColumnInfo(name = "id") @PrimaryKey(autoGenerate = true) var id: Long = 0 @ColumnInfo(name = "calories") var calories: Double = 0.toDouble() } 

PersonalizedFood.kt

 @Entity(primaryKeys = arrayOf("food_id","date")) class PersonalizedFood(@ColumnInfo(name = "quantity") var quantity: Int, @ColumnInfo(name = "unit") var unit: String, @ColumnInfo(name = "date") var date: Date){ @ColumnInfo(name = "food_id") var foodId:Long = 0 } 

FoodDao.kt

 @Dao interface FoodDao { companion object{ const val ID = "id" const val NAME = "name" const val PROTEIN = "protein" const val DESC = "desc" const val CARBS = "carbs" const val FAT = "fat" const val DATE = "date" const val FOOD_ID = "food_id" const val ALL_FOOD_LIST = "food" const val PERSONALISED_FOOD_LIST = "personalised_food" } /** * Returns food details of a food given by food_id */ @Query("SELECT * FROM $ALL_FOOD_LIST WHERE $ID=:food_id") fun getFoodDetails(food_id:Long):Food /** * Inserts food items in all_food_list */ @Insert fun addFoodList(list:ArrayList) @Insert(onConflict = REPLACE) fun saveFood(food:PersonalizedFood) @Query("SELECT * FROM $PERSONALISED_FOOD_LIST WHERE $FOOD_ID=:foodId and $DATE=:date") fun getFood(foodId:Int, data:Date):PersonalizedFood @Query("SELECT * FROM $ALL_FOOD_LIST where $ID in (select $FOOD_ID from $PERSONALISED_FOOD_LIST where $DATE = :date)") fun getFood(date:Date):ArrayList } 

Converter.kt

 class Converter { companion object{ @TypeConverter fun fromTimestamp(value: Long?): Date? { return if (value == null) null else Date(value) } @TypeConverter fun dateToTimestamp(date: Date): Long { return date.time } } } 

FoodDatabase.kt

 @Database(entities = arrayOf(Food::class, PersonalizedFood::class), version = 1) @TypeConverters(Converter::class) abstract class FoodDatabase : RoomDatabase(){ abstract fun foodDao():FoodDao companion object{ private val databaseName = "diet" var dbInstance:FoodDao? = null fun getInstance(context:Context):FoodDao?{ if(dbInstance == null) dbInstance = Room.inMemoryDatabaseBuilder(context, FoodDatabase::class.java).build().foodDao() return dbInstance; } } } 

而当我运行下面的代码来创建数据库:

FoodDatabase.getInstance(baseContext)?.getFood(Calendar.getInstance().time)

它给了我以下例外:

 Caused by: java.lang.RuntimeException: cannot find implementation for com.chandilsachin.diettracker.database.FoodDatabase. FoodDatabase_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.chandilsachin.diettracker.database.FoodDatabase$Companion.getInstance(FoodDatabase.kt:21) at com.chandilsachin.diettracker.MainActivity$SetUpFoodDatabase.doInBackground(MainActivity.kt:95) at com.chandilsachin.diettracker.MainActivity$SetUpFoodDatabase.doInBackground(MainActivity.kt:77) at android.os.AsyncTask$2.call(AsyncTask.java:295) at java.util.concurrent.FutureTask.run(FutureTask.java:237) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) at java.lang.Thread.run(Thread.java:818) 

有没有人在kotlin中实现了空间持久性?

编辑这个问题被标记为这个重复。 虽然问题陈述是相同的,但解决方案并不能解决我的问题。 解决方案说我必须添加替换annotationProcessorkapt "android.arch.persistence.room:compiler:1.0.0-alpha1"依赖项。 我做了这些更改,并在项目构建时导致了gradle错误。

 Information:Gradle tasks [:app:assembleDebug] Warning:warning: Supported source version 'RELEASE_7' from annotation processor 'android.arch.persistence.room.RoomProcessor' less than -source '1.8' Warning:warning: The following options were not recognized by any processor: '[kapt.kotlin.generated]' /Users/BBI-M1025/Documents/BBI/Workspace_fun/Android/diet-tracker/app/src/main/java/com/chandilsachin/diettracker/database/Food.kt Error:(1, 1) Some error(s) occurred while processing annotations. Please see the error messages above. Error:Execution failed for task ':app:kaptDebugKotlin'. > Compilation error. See log for more details Information:BUILD FAILED in 10s Information:2 errors Information:2 warnings Information:See complete output in console 

我也附加我的gradle文件:

 apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-kapt' android { compileSdkVersion 25 buildToolsVersion "25.0.2" defaultConfig { applicationId "com.chandilsachin.diettracker" minSdkVersion 16 targetSdkVersion 25 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" compile 'com.android.support:appcompat-v7:25.0.1' compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha8' compile 'com.android.support:cardview-v7:25.0.1' compile 'com.android.support:recyclerview-v7:25.0.1' compile 'com.github.ne1c:rainbowmvp:1.2.1' compile "org.jetbrains.anko:anko-commons:0.10.0" /*annotationProcessor "android.arch.persistence.room:compiler:1.0.0-alpha1" compile "android.arch.lifecycle:extensions:1.0.0-alpha1" annotationProcessor "android.arch.lifecycle:compiler:1.0.0-alpha1"*/ compile "android.arch.persistence.room:runtime:1.0.0-alpha1" annotationProcessor "android.arch.persistence.room:compiler:1.0.0-alpha1" kapt "android.arch.persistence.room:compiler:1.0.0-alpha1" testCompile 'junit:junit:4.12' } repositories { mavenCentral() } 

有没有人遇到过这个问题?

把这个问题旋转了一会儿之后,我碰到了解决办法。

这真的很难,因为现在还没有正式的教程,博客等来帮助解决这个问题。

我不得不对gradle插件和依赖项的所有组合进行一些命中和试用,因为我知道只有gradle配置有问题。

让我们来解决:

我不得不从build.gradle(:module)文件中删除apply plugin: 'kotlin-kapt' ,并用kapt "android.arch.persistence.room:compiler:1.0.0-alpha1" annotationProcessor "android.arch.persistence.room:compiler:1.0.0-alpha1"替换annotationProcessor "android.arch.persistence.room:compiler:1.0.0-alpha1" kapt "android.arch.persistence.room:compiler:1.0.0-alpha1"

这是成功编译代码的gradle配置。

但有更多的事情要检查。 您必须初始化您的@Entity class属性,这与Room Persistence lib doc中给出的java不同。 虽然有getter setter,但没有提到创建一个具有初始化的构造函数。 所以我不得不改变我的@Entity类:

 @Entity(tableName = "all_food_list") class Food (@ColumnInfo(name = "food_name") var foodName: String = "", @ColumnInfo(name = "food_desc") var foodDesc: String = "", @ColumnInfo(name = "protein") var protein: Double = 0.0, @ColumnInfo(name = "carbs") var carbs: Double = 0.0, @ColumnInfo(name = "fat") var fat: Double = 0.0, @ColumnInfo(name = "calories") var calories: Double = 0.0) { @ColumnInfo(name = "id") @PrimaryKey(autoGenerate = true) var id: Long = 0 } 

现在对于TypeConverts,与java不同,您需要创建普通函数而不是静态函数(伴随对象):

 class Converters{ @TypeConverter fun fromTimestamp(value: String): Calendar { val arr = value.split("-") val cal = Calendar.getInstance() cal.set(arr[0].toInt(), arr[1].toInt(), arr[2].toInt()) return cal } @TypeConverter fun dateToTimestamp(date: Calendar): String { return "${date.get(Calendar.DATE)}-${date.get(Calendar.MONTH)+1}-${date.get(Calendar.YEAR)}" } } 

我正在添加build.gradle文件也使其更加清楚:

的build.gradle(:项目)

 buildscript { ext.kotlin_version = '1.1.2-4' ext.gradle_version_stable = '2.3.2' ext.gradle_version_preview = '3.0.0-alpha1' ext.anko_version = '0.10.0' repositories { maven { url 'https://maven.google.com' } jcenter() } dependencies { classpath 'com.android.tools.build:gradle:3.0.0-alpha1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } allprojects { repositories { maven { url 'https://maven.google.com' } jcenter() maven { url "https://jitpack.io" } } } task clean(type: Delete) { delete rootProject.buildDir } 

的build.gradle(:模块)

 apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' android { compileSdkVersion 25 buildToolsVersion "25.0.2" defaultConfig { applicationId "com.chandilsachin.diettracker" minSdkVersion 16 targetSdkVersion 25 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" ... ... // room persistence dependency compile "android.arch.persistence.room:runtime:1.0.0-alpha1" kapt "android.arch.persistence.room:compiler:1.0.0-alpha1" testCompile 'junit:junit:4.12' } repositories { mavenCentral() } 

我想这是所有的,我做了我的代码woking。

希望这也可以帮助别人。

在这里我的gradle文件,我不需要添加thoses插件。

的build.gradle(项目):

 buildscript { ext.kotlin_version = '1.1.2-4' ext.lifecycle_version = '1.0.0-alpha1' ext.room_version = '1.0.0-alpha1' repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.3.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } 

build.gradle(app)

 apply plugin: 'com.android.application' apply plugin: 'kotlin-android' //enable anotation processing with kotlin, disabled by default kapt { generateStubs = true } android { /** ... **/ } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) //kotlin compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" //support compile 'com.android.support:appcompat-v7:25.3.1' //google architecture compile "android.arch.lifecycle:runtime:$lifecycle_version" compile "android.arch.lifecycle:extensions:$lifecycle_version" annotationProcessor "android.arch.lifecycle:compiler:$lifecycle_version" kapt "android.arch.lifecycle:compiler:$lifecycle_version" //database compile "android.arch.persistence.room:runtime:$room_version" annotationProcessor "android.arch.persistence.room:compiler:$room_version" kapt "android.arch.persistence.room:compiler:$room_version" } repositories { mavenCentral() } 

然后运行菜单build-> make project来创建impl类。 希望这可以帮助

我做了一个类似的使用Java的例子,并使用了相同的问题和解决方案是添加APT行apt“android.arch.persistence.room:compiler:1.0.0-alpha1”

不适用:应用插件:’kotlin-kapt’。 删除这一行!

您必须先清理项目并重新构建,然后再尝试卸载手机或虚拟设备上的现有应用程序。 希望你帮忙。

在我的情况是有点不同。 我使用AS 3.0.0-beta6 。 Kotlin – 1.1.4-31.1.50以及1.0.0-alpha9-1室。 而且因为我使用了gradle 3.0.0,所以我把所有的配置改成了实现,而不是编译 。 它造成问题中所描述的问题出现。

替换implementation "android.arch.persistence.room:runtime:1.0.0-alpha9-1"

compile "android.arch.persistence.room:runtime:1.0.0-alpha9-1"

小费

因为在编辑器中有更好的突出显示,所以使用Java来处理您的DAO。