I am implementing Room persistence lib in kotlin for my database implementation.
Following are my Entity
, Dao
and Database
cla
Here my gradle files, i didn't need to add thoses plugins.
build.gradle(project):
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()
}
Then run menu build-> make project to create impl class. Hope this helps
I made an example similar using Java and used to have same problem and solution was add APT line apt "android.arch.persistence.room:compiler:1.0.0-alpha1"
without apply: apply plugin: 'kotlin-kapt'. Remove this line!!
You have to clear project and rebuild it before run again and try uninstall existing app on phone or Virtual device. Hope you help.
I got the same issue when I try to migrate from Java to Kotlin:
RuntimeException: cannot find implementation for AppDatabase. AppDatabase_Impl does not exist
I tried all these answers in this question, none all them works, then I found an article: Kotlinlang Tutorials - Android Frameworks Using Annotation Processing:
In Kotlin you specify the dependencies in a similar to Java way using Kotlin Annotation processing tool (kapt) instead of annotationProcessor.
Then I modified the build.gradle(Module:app) by changing all annotationProcessor
to kapt
, it works:
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -2,6 +2,8 @@ apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
+apply plugin: 'kotlin-kapt'
apply plugin: 'kotlin-android-extensions'
android {
// Butter Knife
implementation "com.jakewharton:butterknife:$butterknife_version"
- annotationProcessor "com.jakewharton:butterknife-compiler:$butterknife_version"
+ kapt "com.jakewharton:butterknife-compiler:$butterknife_version"
// Room
implementation "android.arch.persistence.room:runtime:$arch_lifecycle_version"
- annotationProcessor "android.arch.persistence.room:compiler:$arch_lifecycle_version"
+ kapt "android.arch.persistence.room:compiler:$arch_lifecycle_version"
// LifeCycle
implementation "android.arch.lifecycle:runtime:$arch_lifecycle_version"
implementation "android.arch.lifecycle:extensions:$arch_lifecycle_version"
implementation "android.arch.lifecycle:common-java8:$arch_lifecycle_version"
- annotationProcessor "android.arch.lifecycle:compiler:$arch_lifecycle_version"
+ kapt "android.arch.lifecycle:compiler:$arch_lifecycle_version"
// Dagger
implementation "com.google.dagger:dagger:$dagger_version"
implementation "com.google.dagger:dagger-android-support:$dagger_version"
- annotationProcessor "com.google.dagger:dagger-compiler:$dagger_version"
- annotationProcessor "com.google.dagger:dagger-android-processor:$dagger_version"
+ kapt "com.google.dagger:dagger-compiler:$dagger_version"
+ kapt "com.google.dagger:dagger-android-processor:$dagger_version"
}
If you use Butter Knife, you should also change to kapt, otherwise the views which are injected might be null.
in the Dao interface check that the annotations like @Query .. are imported from the room database class and not from somewhere else
After spinning my head around for a while with this problem, I came across to the solution.
It was really hard as there is no official tutorial, blog etc out there to help with this problem as of now.
I had to do several hit and trial for all the combination of gradle plugins and dependencies as i knew that something is wrong with gradle config only.
Lets come to the solution:
I had to remove apply plugin: 'kotlin-kapt'
from build.gradle(:module) file
and replace annotationProcessor "android.arch.persistence.room:compiler:1.0.0-alpha1"
to kapt "android.arch.persistence.room:compiler:1.0.0-alpha1"
.
This is the gradle configuration to successfully compile code.
But there more things to check. You have to initialise properties of your @Entity class
unlike java given in Room Persistence lib doc. Though there are getter setter but it is not mentioned to create a constructor with initialisation.
So I had to change my @Entity
class with this:
@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
}
Now for TypeConverts, Unlike java, you need to create normal function not static functions(companion object):
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)}"
}
}
I am adding build.gradle file also to make it more clear:
build.gradle(:project)
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(:module)
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()
}
I think this is all, I did to make my code woking.
Hope this helps someone else also.