简体   繁体   English

房间找不到实现

[英]Room cannot find implementation

I have a problem with testing a Room database: when I run the test, I get this exception:我在测试 Room 数据库时遇到问题:运行测试时,出现以下异常:

java.lang.RuntimeException: cannot find implementation for database.TicketDatabase. TicketDatabase_Impl does not exist
at android.arch.persistence.room.Room.getGeneratedImplementation(Room.java:92)
at android.arch.persistence.room.RoomDatabase$Builder.build(RoomDatabase.java:454)
at com.sw.ing.gestionescontrini.DatabaseTest.setDatabase(DatabaseTest.java:36)
at java.lang.reflect.Method.invoke(Native Method)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:59)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:262)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1886)

Class DatabaseTest: Class 数据库测试:

public class DatabaseTest {

    TicketDatabase database;
    DAO ticketDAO;


    @Before
    public void setDatabase() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Context context = InstrumentationRegistry.getTargetContext();
        database = Room.inMemoryDatabaseBuilder(context, TicketDatabase.class).build();

        Method method = TicketDatabase.class.getDeclaredMethod("ticketDao()");
        method.setAccessible(true);
        ticketDAO = (DAO) method.invoke(database, null);
    }
}

gradle file: gradle 档案:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    buildToolsVersion '26.0.2'
    defaultConfig {
        applicationId "com.sw.ing.gestionescontrini"
        minSdkVersion 15
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    defaultConfig {
        multiDexEnabled true
    }
    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 'com.android.support:appcompat-v7:26.+'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    testCompile 'junit:junit:4.12'

    annotationProcessor 'android.arch.lifecycle:compiler:1.0.0'
    compile 'android.arch.persistence.room:rxjava2:1.0.0-rc1'
    testCompile'android.arch.persistence.room:testing:1.0.0-rc1'

}

I don't really know what this implementation should be, I searched for a solution but all I found doesn't work for me.我真的不知道这个实现应该是什么,我搜索了一个解决方案,但我发现的所有内容都不适合我。 For instance, many found a solution adding kapt "android.arch.persistence.room..." but gradle doesn't recognize "kapt".例如,许多人找到了添加 kapt“android.arch.persistence.room...”的解决方案,但 gradle 无法识别“kapt”。

kapt is for Kotlin. kapt适用于 Kotlin。

First, add:首先,添加:

annotationProcessor "android.arch.persistence.room:compiler:1.0.0"

to your dependencies closure.到您的dependencies闭包。

Then, upgrade android.arch.persistence.room:rxjava2 and android.arch.persistence.room:testing to 1.0.0 instead of 1.0.0-rc1 .然后,将android.arch.persistence.room:rxjava2android.arch.persistence.room:testing升级到1.0.0而不是1.0.0-rc1

ref: https://developer.android.com/jetpack/androidx/releases/room参考: https : //developer.android.com/jetpack/androidx/releases/room

for Kotlin change the 'annotationProcessor' keyword to 'kapt' in gradle file.对于 Kotlin,将 gradle 文件中的“annotationProcessor”关键字更改为“kapt”。

kapt "android.arch.persistence.room:compiler:1.1.1"

and also add on top of the dependency file并在依赖文件的顶部添加

apply plugin: 'kotlin-kapt'

ref: https://developer.android.com/jetpack/androidx/releases/room参考: https : //developer.android.com/jetpack/androidx/releases/room

If You Use Kotlin sure exists this code in your in grade file.如果您使用 Kotlin,请确保在您的成绩文件中存在此代码。

apply plugin: "kotlin-kapt"

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

Documentation: https://developer.android.com/jetpack/androidx/releases/room文档: https : //developer.android.com/jetpack/androidx/releases/room

java.lang.RuntimeException: cannot find implementation for com.example.kermovie.data.repository.local.MoviesDatabase. java.lang.RuntimeException:找不到 com.example.kermovie.data.repository.local.MoviesDatabase 的实现。 MoviesDatabase_Impl does not exist MoviesDatabase_Impl 不存在

You have to add the following to your build.gradle :您必须将以下内容添加到您的build.gradle

apply plugin: 'kotlin-kapt' 

dependencies {
    implementation 'androidx.room:room-runtime:2.3.0'
    implementation "androidx.room:room-ktx:2.3.0"
    kapt "androidx.room:room-compiler:2.3.0"
}

You may have to change the version when a newer version is available.当有新版本可用时,您可能需要更改版本。

I see some people around here (Vishu Bhardwaj and others on similar StackOverflow questions) complains the accepted answer does not work for them.我看到这里的一些人(Vishu Bhardwaj 和其他类似 StackOverflow 问题的人)抱怨接受的答案对他们不起作用。 I think it deserve mentioning I had a similar problem in a MULTI modules project that needed a trick around the accepted answer.我认为值得一提的是,我在 MULTI 模块项目中遇到了类似的问题,需要围绕已接受的答案进行技巧。

In my multi modules project the room database dependencies where included mostly in one basic module and exported using proper api notation but room code was split along 2 different modules.在我的多模块项目中,房间数据库依赖项主要包含在一个基本模块中,并使用适当的 api 符号导出,但房间代码分为 2 个不同的模块。 Project compiled with no warning but java.lang.RuntimeException: cannot find implementation for database... was raised on run-time.项目编译时没有警告,但java.lang.RuntimeException: cannot find implementation for database...在运行时引发。

This was fixed by adding这是通过添加修复的

annotationProcessor "android.arch.persistence.room:compiler:$room_version"

in ALL modules that included Room related code .在包含 Room 相关代码的所有模块中

This gradle works nicely.这个gradle很好用。 Notice the plugin kotlin-kapt at the beggining.请注意开头的插件 kotlin-kapt。 It's crucial.这很关键。

apply plugin: 'kotlin-kapt'
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "????"
        minSdkVersion 21
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'

    implementation 'android.arch.persistence.room:runtime:1.1.1'
    kapt 'android.arch.persistence.room:compiler:1.1.1'
}

I did as everybody said in above answer still no luck.我按照上面答案中的每个人所说的做了仍然没有运气。
The issue on my end was that, I was doing insertion on main thread.我的问题是,我在主线程上进行插入。

roomDatabase = Room.databaseBuilder(DexApplication.getInstance(),MyRoomDatabase.class,"db_name")
                    .fallbackToDestructiveMigration() // this is only for testing, 
                       //migration will be added for release
                    .allowMainThreadQueries() // this solved the issue but remember that its For testing purpose only
                    .build();

Explanation:解释:

.allowMainThreadQueries() 

allows you run queries on the main thread.允许您在主线程上运行查询。 But keep in mind to remove it and implement, RxJava, Live Data or any other background process mechanism for querying database.但请记住删除它并实现 RxJava、Live Data 或任何其他用于查询数据库的后台处理机制。 Hope that would help.希望这会有所帮助。

Add below plugin and dependency添加以下插件和依赖项

apply plugin: 'kotlin-kapt'应用插件:'kotlin-kapt'

kapt "android.arch.persistence.room:compiler:1.1.1" kapt "android.arch.persistence.room:compiler:1.1.1"

I will add complete answer that solved my problem我将添加解决我的问题的完整答案

First add all the room dependency of android x second add apply plugin: 'kotlin-kapt' and replace annotationProcessor of room compiler with kept首先添加android x的所有房间依赖项,第二次添加apply plugin: 'kotlin-kapt'并将room编译器的annotationProcessor替换为keep

In my case, adding the following annotation above the database class solves the problem.就我而言,在数据库类上方添加以下注释可以解决问题。

@Database(entities = {Entities.class}, version = 1, exportSchema = false)
public abstract class TheDatabase extends RoomDatabase {...}

Thanks to @nicklocicero.感谢@nicklocicero。

I'm coming a little bit late but I had the same issue but none of the answers helped me.我来得有点晚,但我遇到了同样的问题,但没有一个答案对我有帮助。 So I hope my experience will help others.所以我希望我的经验能帮助其他人。 Room couldn't find the implementation while executing my instrumentation tests so adding below line to my gradle file fixed the problem Room 在执行我的仪器测试时找不到实现,因此将以下行添加到我的 gradle 文件中解决了问题

kaptAndroidTest "androidx.room:room-compiler:$room_version"

If you use annotation processors for your androidTest or test sources, the respective kapt configurations are named kaptAndroidTest and kaptTest如果您为 androidTest 或测试源使用注释处理器,则相应的 kapt 配置将命名为 kaptAndroidTest 和 kaptTest

it means your room runtime dependency is missing .. please add below dependency in your build.gradle(module) file.这意味着您的房间运行时依赖项丢失.. 请在您的 build.gradle(module) 文件中添加以下依赖项。 This will resolve your issue :)这将解决您的问题:)

 dependencies{

     def room_version = "2.2.6"
        implementation "androidx.room:room-ktx:$room_version"
        implementation "androidx.room:room-runtime:$room_version"
        kapt "androidx.room:room-compiler:$room_version"  
}

Add this in your app module's buld.gradle file将此添加到您的应用程序模块的buld.gradle文件中

    //The Room persistence library provides an abstraction layer over SQLite
    def room_version = "2.3.0"
    implementation("androidx.room:room-runtime:$room_version")
    annotationProcessor "androidx.room:room-compiler:$room_version"

In your data access object file add the follwoing annotation在您的数据访问对象文件中添加以下注释

@Database(entities = [EntityClassName::class], version = 1)

Replace entity class name and database version code as per your project need.根据您的项目需要替换实体类名称和数据库版本代码。

If you are using kotlin, apply kapt plugin to the annotation processor as following line:如果您使用的是 kotlin,请将 kapt 插件应用到注释处理器,如下所示:

apply plugin: 'kotlin-kapt'

Then Replace annotationProcessor "androidx.room:room-compiler:$room_version" with the following line:然后将annotationProcessor "androidx.room:room-compiler:$room_version"替换为以下行:

kapt "androidx.room:room-compiler:$room_version"

I had the same problem.我有同样的问题。 This happens when you forget to add the compiler dependency.当您忘记添加编译器依赖项时会发生这种情况。

Add these dependencies添加这些依赖项

    def room = "2.3.0"
    implementation "androidx.room:room-runtime:$room"
    implementation "androidx.room:room-ktx:$room"
    kapt "androidx.room:room-compiler:$room"

In my case, I was doing a complete rewrite alongside old code and put the new code in a temporary package called new without thinking it might conflict with the Java keyword.就我而言,我在旧代码旁边进行了完全重写,并将新代码放在一个名为new的临时包中,而没有想到它可能与 Java 关键字冲突。 Evidently the Room compiler just ignores packages with that name and I didn't notice any warnings.显然 Room 编译器只是忽略了具有该名称的包,我没有注意到任何警告。 Android Studio allows creating that package, but not renaming to it. Android Studio 允许创建该包,但不能重命名它。 I renamed the package to redesign and it worked.我将包重命名为redesign并且它有效。

add this添加这个

@Database(entities = [Entity::class], version = 1) to your db class @Database(entities = [Entity::class], version = 1)到你的数据库 class

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM