【问题标题】:What is Impl file and under what conditions is the Impl file automatically generated?什么是Impl文件,在什么条件下会自动生成Impl文件?
【发布时间】:2020-11-29 14:01:00
【问题描述】:

我正在使用 Room Database 制作 ToDo 应用程序。我得到了 kaptDebugKotlin 构建错误,所以一直在找到原因。现在我发现了,但有一些问题。我创建了新项目并将问题部分(房间数据库代码)复制到那里。我看到数据库部分的代码在测试项目中自动生成 Impl 文件(ToDoDatabase_Impl.java 等)并且构建良好,但它没有在我的主项目中生成 Impl 并且无法构建。

什么是Impl文件?什么情况下会自动生成Impl文件?

我将每个 annotationProcessor 都更改为 kapt。

我的代码如下。

ToDoDao.kt

package com.overeasy.hiptodo.model

import androidx.room.*

@Dao
interface ToDoDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insert(toDo: ToDo)

    @Update(onConflict = OnConflictStrategy.REPLACE)
    suspend fun update(toDo: ToDo)

    @Delete
    suspend fun delete(toDo: ToDo)
}

ToDoDatabase.kt

package com.overeasy.hiptodo.model

import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase

@Database(
entities = [ToDo::class],
version = 1
)
abstract class ToDoDatabase : RoomDatabase() {
    abstract fun toDoDao(): ToDoDao

    companion object {
        @Volatile
        private var INSTANCE: ToDoDatabase? = null

        fun getInstance(context: Context) : ToDoDatabase? {
            if (INSTANCE == null) {
                synchronized(this) {
                    INSTANCE = Room.databaseBuilder(
                        context.applicationContext,
                        ToDoDatabase::class.java,
                        "todo_database"
                    ).build()
                }
            }
            return INSTANCE
        }
    }
}

ToDo.kt

package com.overeasy.hiptodo.model

import androidx.room.Entity
import androidx.room.Ignore
import androidx.room.PrimaryKey

@Entity
class ToDo {
    @PrimaryKey(autoGenerate = true)
    var id: Int? = null

    var something: String
    var date: Long?

    @Ignore
    var day: Long? = null

    constructor(something: String) {
        this.something = something
        this.date = null
    }

    constructor(something: String, date: Long) {
        this.something = something
        this.date = date
    }
}

build.gradle (:app)

plugins {
    id "com.android.application"
    id "kotlin-android"
    id "kotlin-kapt"
}

repositories {
    jcenter()
}

android {
    compileSdkVersion 30
    buildToolsVersion "30.0.0"

    defaultConfig {
        applicationId "com.overeasy.hiptodo"
        minSdkVersion 16
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

        multiDexEnabled = true
        vectorDrawables.useSupportLibrary = true

        javaCompileOptions {
            annotationProcessorOptions {
                arguments += [
                        "room.schemaLocation":"$projectDir/schemas".toString(),
                        "room.incremental":"true",
                        "room.expandProjection":"true"]
            }
        }
    }

    buildFeatures {
        dataBinding true
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"
        }
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    kotlinOptions {
        jvmTarget = '1.8'
    }
}

    dependencies {
    def roomVersion = "2.2.5"

    implementation "org.jetbrains.kotlin:kotlin-stdlib:1.4.20"
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.4.20"
    implementation "androidx.core:core-ktx:1.3.2"
    implementation "androidx.appcompat:appcompat:1.2.0"
    implementation "androidx.constraintlayout:constraintlayout:2.0.4"
    implementation "androidx.cardview:cardview:1.0.0"
    implementation "androidx.recyclerview:recyclerview:1.1.0"
    implementation "com.google.android.material:material:1.2.1"
    implementation "androidx.multidex:multidex:2.0.1"
    implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
    implementation "io.reactivex.rxjava2:rxjava:2.2.19"
    implementation "io.reactivex.rxjava2:rxkotlin:2.4.0"
    implementation "io.reactivex.rxjava2:rxandroid:2.1.1"
    implementation "com.jakewharton.rxbinding4:rxbinding:4.0.0"
    implementation "com.jakewharton.rxbinding4:rxbinding-recyclerview:4.0.0"
    implementation "com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0"
    implementation "io.sentry:sentry-android:3.1.0"
    implementation "androidx.room:room-ktx:$roomVersion"
    kapt "androidx.room:room-compiler:$roomVersion"
    testImplementation "junit:junit:4.13.1"
    androidTestImplementation "androidx.test.ext:junit:1.1.2"
    androidTestImplementation "androidx.test.espresso:espresso-core:3.3.0"
}

这太可怕了。我已经花了将近 2 周的时间来解决这个问题。但是还是不行。

【问题讨论】:

    标签: android kotlin


    【解决方案1】:

    当你做toDoDao.insert(someToDo)时,你必须问自己,这段代码是如何工作的? abstactinterfacefunctions不能调用,那么insert(ToDo)function的实现在哪里呢?

    @Dao接口中定义的所有函数的实现都在YourDao_impl(impl implementation的缩写,你的@Dao interface的实现)里面,由annotation处理器自动生成。

    要了解 _impl 类的使用,您必须了解在读取或写入 SQL databases 时,几乎总是需要执行多个步骤。在大多数情况下,这些步骤如下所示:

    1. Connect to database (In case of android, need to use SQLiteOpenHelper)
    2. prepare the query to be executed
    3. execute query and receive result
    4. build a model from received result (In your case ToDo)
    

    但是当使用room 时,你只定义了一个interface@Dao annotation 包含abstract functions 标有某些annotations@Insert@Update,@987654341 等。 )。 room 所做的是自动生成(使用annotation 处理器)上面列出的所有功能的常用步骤。

    【讨论】:

      【解决方案2】:

      我解决了这个 sh×tshow !!!这个该死的错误是由Entity 的多个构造函数造成的。 Room 只接受一个构造函数。如果有人想要 Entity 类中的 2 个或更多构造函数,请在子构造函数上方使用 @Ignore 注释。

      附:我得到了KaptDebugError_Impl does not exist error。如果有人在 build.gradle 中放置了正确的依赖项,或者确实复制并粘贴了它们,请检查您的 Entity 的构造函数。这不是 Veritas,但可以成为某人的解决方案。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-23
        • 2013-12-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多