房间找不到执行

我在测试 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)

类别资料库测试:

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);
}
}

档案:

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'


}

我真的不知道这个实现应该是什么,我寻找了一个解决方案,但我找到的所有都不适合我。例如,许多人发现了一个解决方案,它添加了 kapt“ android.arch.persence.room...”,但 gradle 不能识别“ kapt”。

61160 次浏览

kapt is for Kotlin.

First, add:

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

to your dependencies closure.

Then, upgrade android.arch.persistence.room:rxjava2 and android.arch.persistence.room:testing to 1.0.0 instead of 1.0.0-rc1.

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

I see some people around here (Vishu Bhardwaj and others on similar StackOverflow questions) complains the accepted answer does not work for them. I think it deserve mentioning I had a similar problem in a MULTI modules project that needed a trick around the accepted answer.

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. Project compiled with no warning but java.lang.RuntimeException: cannot find implementation for database... was raised on run-time.

This was fixed by adding

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

in ALL modules that included Room related code.

for Kotlin change the 'annotationProcessor' keyword to 'kapt' in gradle file.

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

This gradle works nicely. Notice the plugin kotlin-kapt at the beggining. 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'
}

If You Use Kotlin sure exists this code in your in grade file.

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

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. Hope that would help.

Add below plugin and dependency

apply plugin: 'kotlin-kapt'

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

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

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

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.

java.lang.RuntimeException: cannot find implementation for com.example.kermovie.data.repository.local.MoviesDatabase. MoviesDatabase_Impl does not exist

You have to add the following code to your build.gradle:

apply plugin: 'kotlin-kapt'


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

You may have to change the room_version variable when a newer version is available.

You can check for a newer version on the following web mvnrepository.com

it means your room runtime dependency is missing .. please add below dependency in your build.gradle(module) file. 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

    //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:

apply plugin: 'kotlin-kapt'

Then Replace annotationProcessor "androidx.room:room-compiler:$room_version" with the following line:

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. Evidently the Room compiler just ignores packages with that name without giving warnings. Android Studio doesn't warn when creating a new package, but it does say "not a valid package name" when entered in the rename dialog even though it still allows renaming to that. I renamed the package to redesign and no longer had the issue.

add this

@Database(entities = [Entity::class], version = 1) to your db class