房间找不到实现
Room cannot find implementation
我在测试 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.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.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=10=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.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.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=10=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.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 数据库测试:
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 文件:
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.persistence.room..." 但 gradle 无法识别 "kapt".
的解决方案
kapt
适用于 Kotlin。
首先,添加:
annotationProcessor "android.arch.persistence.room:compiler:1.0.0"
你的 dependencies
闭包。
然后,将 android.arch.persistence.room:rxjava2
和 android.arch.persistence.room:testing
升级到 1.0.0
而不是 1.0.0-rc1
。
参考:https://developer.android.com/jetpack/androidx/releases/room
我看到这里的一些人(Vishu Bhardwaj 和其他人在类似的 Whosebug 问题上)抱怨接受的答案对他们不起作用。我认为值得一提的是我在一个多模块项目中遇到了类似的问题,需要一个技巧来解决已接受的答案。
在我的多模块项目中,房间数据库依赖项主要包含在一个基本模块中,并使用适当的 api 符号导出,但房间代码分为 2 个不同的模块。项目编译时没有警告,但 java.lang.RuntimeException:找不到数据库的实现... 是在 运行 时间提出的。
已通过添加解决此问题
annotationProcessor "android.arch.persistence.room:compiler:$room_version"
在包含房间相关代码的所有模块中。
对于 Kotlin,将 gradle 文件中的 'annotationProcessor' 关键字更改为 'kapt'。
kapt "android.arch.persistence.room:compiler:1.1.1"
并在依赖文件之上添加
apply plugin: 'kotlin-kapt'
参考:https://developer.android.com/jetpack/androidx/releases/room
这个gradle效果很好。注意开头的插件 kotlin-kapt。很关键。
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'
}
如果您使用 Kotlin,您的年级文件中肯定存在此代码。
apply plugin: "kotlin-kapt"
// Room
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
文档:https://developer.android.com/jetpack/androidx/releases/room
我按照上面回答大家说的做了,还是不行。
我这边的问题是,我在主线程上进行插入。
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();
解释:
.allowMainThreadQueries()
允许您 运行 在主线程上查询。但请记住删除它并实现 RxJava、Live Data 或任何其他用于查询数据库的后台进程机制。
希望能有所帮助。
添加以下插件和依赖
应用插件:'kotlin-kapt'
卡普特 "android.arch.persistence.room:compiler:1.1.1"
我将添加解决我问题的完整答案
首先添加androidx的所有房间依赖
第二个添加应用插件:'kotlin-kapt' 并将 room compiler 的 annotationProcessor 替换为 keeped
我来晚了一点,但我遇到了同样的问题,但 none 的答案对我有帮助。所以我希望我的经历能对其他人有所帮助。
Room 在执行我的仪器测试时找不到实现,因此将以下行添加到我的 gradle 文件中解决了问题
kaptAndroidTest "androidx.room:room-compiler:$room_version"
如果您为 androidTest 或测试源使用注释处理器,则相应的 kapt 配置被命名为 kaptAndroidTest 和 kaptTest
在我的例子中,在数据库上方添加以下注释 class 解决了问题。
@Database(entities = {Entities.class}, version = 1, exportSchema = false)
public abstract class TheDatabase extends RoomDatabase {...}
感谢@nicklocicero。
java.lang.RuntimeException: cannot find implementation for
com.example.kermovie.data.repository.local.MoviesDatabase.
MoviesDatabase_Impl does not exist
您必须将以下代码添加到您的 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"
}
当有新版本可用时,您可能需要更改版本。
您可以在以下网站上查看更新版本mvnrepository.com
这意味着您的房间运行时依赖项缺失.. 请在您的 build.gradle(module) 文件中添加以下依赖项。这将解决您的问题:)
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"
}
将此添加到您的应用模块的 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"
在您的数据访问对象文件中添加以下注释
@Database(entities = [EntityClassName::class], version = 1)
根据您的项目需要替换实体 class 名称和数据库版本代码。
如果您使用的是 kotlin,请按以下行将 kapt 插件应用于注释处理器:
apply plugin: 'kotlin-kapt'
然后将 annotationProcessor "androidx.room:room-compiler:$room_version"
替换为以下行:
kapt "androidx.room:room-compiler:$room_version"
我遇到了同样的问题。当您忘记添加编译器依赖项时会发生这种情况。
添加这些依赖项
def room = "2.3.0"
implementation "androidx.room:room-runtime:$room"
implementation "androidx.room:room-ktx:$room"
kapt "androidx.room:room-compiler:$room"
就我而言,我正在对旧代码进行完全重写,并将新代码放入一个名为 new
的临时包中,而没有考虑它可能与 Java 关键字冲突。显然,Room 编译器只是忽略了具有该名称的包而不发出警告。 Android Studio 在创建 new
包时不会发出警告,但在重命名对话框中输入时它会提示“不是有效的包名称”,即使它仍然允许重命名。我将包重命名为 redesign
并且不再有问题。
我在测试 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.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.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=10=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.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.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=10=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.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 数据库测试:
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 文件:
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.persistence.room..." 但 gradle 无法识别 "kapt".
的解决方案kapt
适用于 Kotlin。
首先,添加:
annotationProcessor "android.arch.persistence.room:compiler:1.0.0"
你的 dependencies
闭包。
然后,将 android.arch.persistence.room:rxjava2
和 android.arch.persistence.room:testing
升级到 1.0.0
而不是 1.0.0-rc1
。
参考:https://developer.android.com/jetpack/androidx/releases/room
我看到这里的一些人(Vishu Bhardwaj 和其他人在类似的 Whosebug 问题上)抱怨接受的答案对他们不起作用。我认为值得一提的是我在一个多模块项目中遇到了类似的问题,需要一个技巧来解决已接受的答案。
在我的多模块项目中,房间数据库依赖项主要包含在一个基本模块中,并使用适当的 api 符号导出,但房间代码分为 2 个不同的模块。项目编译时没有警告,但 java.lang.RuntimeException:找不到数据库的实现... 是在 运行 时间提出的。
已通过添加解决此问题
annotationProcessor "android.arch.persistence.room:compiler:$room_version"
在包含房间相关代码的所有模块中。
对于 Kotlin,将 gradle 文件中的 'annotationProcessor' 关键字更改为 'kapt'。
kapt "android.arch.persistence.room:compiler:1.1.1"
并在依赖文件之上添加
apply plugin: 'kotlin-kapt'
参考:https://developer.android.com/jetpack/androidx/releases/room
这个gradle效果很好。注意开头的插件 kotlin-kapt。很关键。
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'
}
如果您使用 Kotlin,您的年级文件中肯定存在此代码。
apply plugin: "kotlin-kapt"
// Room
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
文档:https://developer.android.com/jetpack/androidx/releases/room
我按照上面回答大家说的做了,还是不行。
我这边的问题是,我在主线程上进行插入。
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();
解释:
.allowMainThreadQueries()
允许您 运行 在主线程上查询。但请记住删除它并实现 RxJava、Live Data 或任何其他用于查询数据库的后台进程机制。 希望能有所帮助。
添加以下插件和依赖
应用插件:'kotlin-kapt'
卡普特 "android.arch.persistence.room:compiler:1.1.1"
我将添加解决我问题的完整答案
首先添加androidx的所有房间依赖 第二个添加应用插件:'kotlin-kapt' 并将 room compiler 的 annotationProcessor 替换为 keeped
我来晚了一点,但我遇到了同样的问题,但 none 的答案对我有帮助。所以我希望我的经历能对其他人有所帮助。 Room 在执行我的仪器测试时找不到实现,因此将以下行添加到我的 gradle 文件中解决了问题
kaptAndroidTest "androidx.room:room-compiler:$room_version"
如果您为 androidTest 或测试源使用注释处理器,则相应的 kapt 配置被命名为 kaptAndroidTest 和 kaptTest
在我的例子中,在数据库上方添加以下注释 class 解决了问题。
@Database(entities = {Entities.class}, version = 1, exportSchema = false)
public abstract class TheDatabase extends RoomDatabase {...}
感谢@nicklocicero。
java.lang.RuntimeException: cannot find implementation for com.example.kermovie.data.repository.local.MoviesDatabase. MoviesDatabase_Impl does not exist
您必须将以下代码添加到您的 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"
}
当有新版本可用时,您可能需要更改版本。 您可以在以下网站上查看更新版本mvnrepository.com
这意味着您的房间运行时依赖项缺失.. 请在您的 build.gradle(module) 文件中添加以下依赖项。这将解决您的问题:)
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"
}
将此添加到您的应用模块的 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"
在您的数据访问对象文件中添加以下注释
@Database(entities = [EntityClassName::class], version = 1)
根据您的项目需要替换实体 class 名称和数据库版本代码。
如果您使用的是 kotlin,请按以下行将 kapt 插件应用于注释处理器:
apply plugin: 'kotlin-kapt'
然后将 annotationProcessor "androidx.room:room-compiler:$room_version"
替换为以下行:
kapt "androidx.room:room-compiler:$room_version"
我遇到了同样的问题。当您忘记添加编译器依赖项时会发生这种情况。
添加这些依赖项
def room = "2.3.0"
implementation "androidx.room:room-runtime:$room"
implementation "androidx.room:room-ktx:$room"
kapt "androidx.room:room-compiler:$room"
就我而言,我正在对旧代码进行完全重写,并将新代码放入一个名为 new
的临时包中,而没有考虑它可能与 Java 关键字冲突。显然,Room 编译器只是忽略了具有该名称的包而不发出警告。 Android Studio 在创建 new
包时不会发出警告,但在重命名对话框中输入时它会提示“不是有效的包名称”,即使它仍然允许重命名。我将包重命名为 redesign
并且不再有问题。