Room Persistence lib implementation in Kotlin

后端 未结 5 1158
栀梦
栀梦 2020-12-03 17:23

I am implementing Room persistence lib in kotlin for my database implementation.

Following are my Entity, Dao and Database cla

相关标签:
5条回答
  • 2020-12-03 17:42

    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

    0 讨论(0)
  • 2020-12-03 17:49

    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.

    0 讨论(0)
  • 2020-12-03 17:52

    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.

    0 讨论(0)
  • 2020-12-03 17:53

    in the Dao interface check that the annotations like @Query .. are imported from the room database class and not from somewhere else

    0 讨论(0)
  • 2020-12-03 18:04

    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.

    0 讨论(0)
提交回复
热议问题