簡體   English   中英

java.lang.RuntimeException:找不到 com.example.laptopsdb.AppDatabase 的實現。 AppDatabase_Impl 不存在(2022 年 7 月)

[英]java.lang.RuntimeException: cannot find implementation for com.example.laptopsdb.AppDatabase. AppDatabase_Impl does not exist (July 2022)

是的,我已經嘗試過一些舊指南,我在下面進行了描述。

我在 Kotlin Android 中為 Room Database 創建了新項目。 我遵循了官方的谷歌文檔。

https://developer.android.com/training/data-storage/room

如果我按照文檔進行操作,我會收到錯誤

java.lang.RuntimeException: cannot find implementation for com.example.laptopsdb.AppDatabase. AppDatabase_Impl does not exist

我也嘗試將 room-runtime 更改為 room-ktx 但錯誤是一樣的。 此外,我嘗試添加 id 'kotlin-kapt' 並將 annotationProcessor 更改為 kapt 但這給了我以下錯誤,實際上是一堆錯誤,同時自動打開 UserDao.java 文件

https://github.com/subjectOneThree/StackOverFLowShares/blob/main/Screenshot_20220715_215040.png

根據文檔,我的代碼幾乎是庫存,但是如果我犯了任何愚蠢的錯誤,你可以檢查一下

build.gradle(應用程序)

plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'

    //id 'kotlin-kapt'
}

android {
    compileSdk 32

    defaultConfig {
        applicationId "com.example.laptopsdb"
        minSdk 21
        targetSdk 32
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    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 {

    apply plugin: "kotlin-kapt"

    implementation 'androidx.core:core-ktx:1.7.0'
    implementation 'androidx.appcompat:appcompat:1.4.2'
    implementation 'com.google.android.material:material:1.6.1'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'

    def room_version = "2.4.2"

    //implementation "androidx.room:room-ktx:$room_version"

    implementation "androidx.room:room-runtime:$room_version"
    annotationProcessor "androidx.room:room-compiler:$room_version"
    //kapt "androidx.room:room-compiler:$room_version"

    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4")
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")
}

用戶.kt

@Entity (tableName = "laptops")
data class User(
    @PrimaryKey val uid: Int,
    @ColumnInfo(name = "first_name") val firstName: String?,
    @ColumnInfo(name = "last_name") val lastName: String?
)

用戶道.kt

@Dao
interface UserDao {
    @Query("SELECT * FROM laptops")
    suspend fun getAll(): List<User>

    @Query("SELECT * FROM user WHERE uid IN (:userIds)")
    suspend fun loadAllByIds(userIds: IntArray): List<User>

    @Query("SELECT * FROM user WHERE first_name LIKE :first AND " +
            "last_name LIKE :last LIMIT 1")
    suspend fun findByName(first: String, last: String): User

    @Insert
    suspend fun insertAll(vararg users: User)

    @Delete
    suspend fun delete(user: User)
}

應用數據庫.kt

@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
}

MainActivity.kt

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val db = Room.databaseBuilder(
            applicationContext,
            AppDatabase::class.java, "laptops"
        ).build()

        val userDao = db.userDao()

        GlobalScope.launch(Dispatchers.Default) {
            userDao.insertAll(User(2,"Hello","World"))

            val users: List<User> = userDao.getAll()
            Log.d("Room Activity", users.toString())
        }


    }
}

一些較舊的項目和我朋友的一個項目具有完全相同的代碼(據我研究),它們運行良好。 但是現在當我嘗試創建新項目時,它給了我錯誤。 在發布到這里之前,我已經嘗試過構建幾個項目。

  1. (評論)這樣做:
val db = Room.databaseBuilder(
            applicationContext,
            AppDatabase::class.java, "laptops"
        ).build()

在 mainActivity 的 onCreate 中創建數據庫實例是一種非常糟糕的方式,除非您希望在一個應用程序中有多個數據庫實例!

  1. 解決方案:

嘗試將您的 build.gradle 更改為:

plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'
}
apply plugin: 'kotlin-kapt'

android {
    compileSdk 32

    defaultConfig {
        applicationId "com.example.laptopsdb"
        minSdk 21
        targetSdk 32
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    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 {
    implementation 'androidx.core:core-ktx:1.7.0'
    implementation 'androidx.appcompat:appcompat:1.4.2'
    implementation 'com.google.android.material:material:1.6.1'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'

    def room_version = "2.4.2"

    kapt("androidx.room:room-compiler:2.4.2")
    implementation("androidx.room:room-runtime:2.4.2")
    implementation("androidx.room:room-ktx:2.4.2")

    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4")
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")
}

編輯:使用相同的代碼創建項目后,我注意到一些相當奇怪的錯誤:

  1. 在您的 User.kt 文件中,您將該實體的表名聲明為“筆記本電腦”,但在您的 UserDao 中,您仍然引用了一個名為 user 的表,該表不存在 (???),這就是為什么房間與您的道

  2. 您將您的 uid 聲明為主鍵,它不應該重復,每個鍵都應該不同,但在您的主要活動中,您使用“userDao.insertAll(User(2,"Hello","World"))" ,這將導致第二次運行時崩潰,只需刪除該行

  3. 使用“GlobalScope.launch(Dispatchers.Default)”來運行協程並不被鼓勵,GlobalScope 甚至在 android studio 中被標記為一個微妙的 API,並且在沒有適當知識的情況下首先使用它可能會導致奇怪的錯誤甚至內存泄漏,只需使用 viewModel 來處理所有工作

  4. 正如我之前所說,

        val db = Room.databaseBuilder(
            applicationContext,
            AppDatabase::class.java, "laptops"
        ).build()

不要用它來創建數據庫實例

  1. 將您的 build.gradle 更新為:
plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'
}
apply plugin: 'kotlin-kapt'

android {
    compileSdk 32

    defaultConfig {
        applicationId "com.example.laptopsdb"
        minSdk 21
        targetSdk 32
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    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 {

    implementation 'androidx.core:core-ktx:1.7.0'
    implementation 'androidx.appcompat:appcompat:1.4.2'
    implementation 'com.google.android.material:material:1.6.1'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'

    // you may add the variable, just keep the version correct
    implementation "androidx.room:room-runtime:2.5.0-alpha02"
    implementation "androidx.room:room-ktx:2.5.0-alpha02"
    kapt "androidx.room:room-compiler:2.5.0-alpha02"

    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4")
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")
}

和道:

@Dao
interface UserDao {
    @Query("SELECT * FROM laptops")
    suspend fun getAll(): List<User>

    @Query("SELECT * FROM laptops WHERE uid IN (:userIds)")
    suspend fun loadAllByIds(userIds: IntArray): List<User>

    @Query("SELECT * FROM laptops WHERE first_name LIKE :first AND " +
            "last_name LIKE :last LIMIT 1")
    suspend fun findByName(first: String, last: String): User

    @Insert
    suspend fun insertAll(vararg users: User)

    @Delete
    suspend fun delete(user: User)
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM