如何解决 ViewModel RunTimeException
How to resolve the ViewModel RunTimeException
我的 ViewModel class 正在抛出 RunTimeException
。它基本上无法创建 ViewModel class 的实例。这是堆栈跟踪:
2019-05-29 01:27:56.700 9698-9698/com.example.cryptpass_kt E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.cryptpass_kt, PID: 9698
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.cryptpass_kt/com.example.cryptpass_kt.MainActivity}: java.lang.RuntimeException: Cannot create an instance of class com.example.cryptpass_kt.EntryViewModel
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2853)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2928)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1609)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6703)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:769)
Caused by: java.lang.RuntimeException: Cannot create an instance of class com.example.cryptpass_kt.EntryViewModel
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:208)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:135)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:103)
at com.example.cryptpass_kt.MainActivity.onCreate(MainActivity.kt:40)
at android.app.Activity.performCreate(Activity.java:6980)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2806)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2928)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1609)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6703)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:769)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:334)
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:200)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:135)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:103)
at com.example.cryptpass_kt.MainActivity.onCreate(MainActivity.kt:40)
at android.app.Activity.performCreate(Activity.java:6980)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2806)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2928)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1609)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6703)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:769)
Caused by: java.lang.RuntimeException: cannot find implementation for com.example.cryptpass_kt.EntryDatabase. EntryDatabase_Impl does not exist
at androidx.room.Room.getGeneratedImplementation(Room.java:94)
at androidx.room.RoomDatabase$Builder.build(RoomDatabase.java:667)
at com.example.cryptpass_kt.EntryDatabase$Companion.getInstance(EntryDatabase.kt:17)
at com.example.cryptpass_kt.EntryRepository.<init>(EntryRepository.kt:12)
at com.example.cryptpass_kt.EntryViewModel.<init>(EntryViewModel.kt:8)
错误指向应用程序中的 4 个不同位置,它们都源于同一个问题。例如,我的 MainActivity.kt
的 onCreate()
方法中的这些行在堆栈跟踪中:
override fun onCreate(savedInstanceState: Bundle?) {
...
viewModel = ViewModelProviders.of(this).get(EntryViewModel::class.java)
viewModel.allEntries.observe(this, Observer { entries -> adapter.submitList(entries) })
...
}
我遵循了 SO 中的一些建议,例如将 ViewModel 对象初始化为 lateinit
而不是 null
但到目前为止它还没有对情况进行任何更改
EntryViewModel.kt
class EntryViewModel(application: Application) : AndroidViewModel(application) {
private val repository: EntryRepository = EntryRepository(application)
val allEntries: LiveData<List<Entry>>
init {
allEntries = repository.allEntries!!
}
fun insert(entry: Entry) {
repository.insert(entry)
}
fun update(entry: Entry) {
repository.update(entry)
}
fun delete(entry: Entry) {
repository.update(entry)
}
fun deleteAll() {
repository.deleteAllEntries()
}
}
EntryDatabase.kt
@Database(entities = [Entry::class], version = 1)
abstract class EntryDatabase : RoomDatabase() {
abstract fun entryDAO(): EntryDAO
companion object{
private var instance: EntryDatabase? = null
@Synchronized
fun getInstance(context: Context): EntryDatabase{
if(instance == null){instance = Room.databaseBuilder<EntryDatabase>(context.applicationContext, EntryDatabase::class.java, "entry_database").fallbackToDestructiveMigration().build()}
return instance as EntryDatabase
}
}
}
而且我拥有所有必要的 gradle 依赖项:
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.core:core-ktx:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.recyclerview:recyclerview:1.1.0-alpha05'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'com.android.support:design:28.1.0'
implementation "android.arch.lifecycle:extensions:2.2.0-alpha01"
implementation "android.arch.persistence.room:runtime:2.1.0-beta01"
implementation "android.arch.paging:runtime:2.1.0-beta01"
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
implementation 'io.sentry:sentry-android:1.7.16'
implementation 'org.slf4j:slf4j-nop:1.7.25'
}
在您发布的堆栈跟踪中,异常被一个一个地放入另一个中。所以最后一个是问题的主要根源:
Caused by: java.lang.RuntimeException: cannot find implementation for com.example.cryptpass_kt.EntryDatabase. EntryDatabase_Impl does not exist
at androidx.room.Room...
正如我从堆栈跟踪中看到的那样,您在尝试获取数据库实例时出错。我不认为在 ViewModel
构造函数中获取数据库引用是个好主意,但这不是必需的。
关于您的数据库代码:有一些可能的原因。
1.依赖关系。
正如我在类似问题的其他答案中看到的那样(我认为 是最好的)你应该添加一些 gradle 依赖项:
// Extensions = ViewModel + LiveData
implementation "android.arch.lifecycle:extensions:1.1.0"
kapt "android.arch.lifecycle:compiler:1.1.0"
// Room
implementation "android.arch.persistence.room:runtime:1.0.0"
kapt "android.arch.persistence.room:compiler:1.0.0"
如果我做对了,Kotlin 只需要一些额外的依赖项(使用关键字 kapt
而不是 implementation
)。
2。注释.
另一个可能的原因:您没有在 Entry
class 中添加 Entity
注释(如 中所述)。另一个需要的注释是 Database
,但您已经有了它。
试试这个
val viewModel = ViewModelProviders.of(this).get(EntryViewModel::class.java)
并在您的应用中 build.gradle
implementation 'android.arch.lifecycle:extensions:1.1.1'
我的 ViewModel class 正在抛出 RunTimeException
。它基本上无法创建 ViewModel class 的实例。这是堆栈跟踪:
2019-05-29 01:27:56.700 9698-9698/com.example.cryptpass_kt E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.cryptpass_kt, PID: 9698
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.cryptpass_kt/com.example.cryptpass_kt.MainActivity}: java.lang.RuntimeException: Cannot create an instance of class com.example.cryptpass_kt.EntryViewModel
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2853)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2928)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1609)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6703)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:769)
Caused by: java.lang.RuntimeException: Cannot create an instance of class com.example.cryptpass_kt.EntryViewModel
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:208)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:135)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:103)
at com.example.cryptpass_kt.MainActivity.onCreate(MainActivity.kt:40)
at android.app.Activity.performCreate(Activity.java:6980)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2806)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2928)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1609)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6703)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:769)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:334)
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:200)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:135)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:103)
at com.example.cryptpass_kt.MainActivity.onCreate(MainActivity.kt:40)
at android.app.Activity.performCreate(Activity.java:6980)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2806)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2928)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1609)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6703)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:769)
Caused by: java.lang.RuntimeException: cannot find implementation for com.example.cryptpass_kt.EntryDatabase. EntryDatabase_Impl does not exist
at androidx.room.Room.getGeneratedImplementation(Room.java:94)
at androidx.room.RoomDatabase$Builder.build(RoomDatabase.java:667)
at com.example.cryptpass_kt.EntryDatabase$Companion.getInstance(EntryDatabase.kt:17)
at com.example.cryptpass_kt.EntryRepository.<init>(EntryRepository.kt:12)
at com.example.cryptpass_kt.EntryViewModel.<init>(EntryViewModel.kt:8)
错误指向应用程序中的 4 个不同位置,它们都源于同一个问题。例如,我的 MainActivity.kt
的 onCreate()
方法中的这些行在堆栈跟踪中:
override fun onCreate(savedInstanceState: Bundle?) {
...
viewModel = ViewModelProviders.of(this).get(EntryViewModel::class.java)
viewModel.allEntries.observe(this, Observer { entries -> adapter.submitList(entries) })
...
}
我遵循了 SO 中的一些建议,例如将 ViewModel 对象初始化为 lateinit
而不是 null
但到目前为止它还没有对情况进行任何更改
EntryViewModel.kt
class EntryViewModel(application: Application) : AndroidViewModel(application) {
private val repository: EntryRepository = EntryRepository(application)
val allEntries: LiveData<List<Entry>>
init {
allEntries = repository.allEntries!!
}
fun insert(entry: Entry) {
repository.insert(entry)
}
fun update(entry: Entry) {
repository.update(entry)
}
fun delete(entry: Entry) {
repository.update(entry)
}
fun deleteAll() {
repository.deleteAllEntries()
}
}
EntryDatabase.kt
@Database(entities = [Entry::class], version = 1)
abstract class EntryDatabase : RoomDatabase() {
abstract fun entryDAO(): EntryDAO
companion object{
private var instance: EntryDatabase? = null
@Synchronized
fun getInstance(context: Context): EntryDatabase{
if(instance == null){instance = Room.databaseBuilder<EntryDatabase>(context.applicationContext, EntryDatabase::class.java, "entry_database").fallbackToDestructiveMigration().build()}
return instance as EntryDatabase
}
}
}
而且我拥有所有必要的 gradle 依赖项:
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.core:core-ktx:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.recyclerview:recyclerview:1.1.0-alpha05'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'com.android.support:design:28.1.0'
implementation "android.arch.lifecycle:extensions:2.2.0-alpha01"
implementation "android.arch.persistence.room:runtime:2.1.0-beta01"
implementation "android.arch.paging:runtime:2.1.0-beta01"
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
implementation 'io.sentry:sentry-android:1.7.16'
implementation 'org.slf4j:slf4j-nop:1.7.25'
}
在您发布的堆栈跟踪中,异常被一个一个地放入另一个中。所以最后一个是问题的主要根源:
Caused by: java.lang.RuntimeException: cannot find implementation for com.example.cryptpass_kt.EntryDatabase. EntryDatabase_Impl does not exist
at androidx.room.Room...
正如我从堆栈跟踪中看到的那样,您在尝试获取数据库实例时出错。我不认为在 ViewModel
构造函数中获取数据库引用是个好主意,但这不是必需的。
关于您的数据库代码:有一些可能的原因。
1.依赖关系。
正如我在类似问题的其他答案中看到的那样(我认为
// Extensions = ViewModel + LiveData
implementation "android.arch.lifecycle:extensions:1.1.0"
kapt "android.arch.lifecycle:compiler:1.1.0"
// Room
implementation "android.arch.persistence.room:runtime:1.0.0"
kapt "android.arch.persistence.room:compiler:1.0.0"
如果我做对了,Kotlin 只需要一些额外的依赖项(使用关键字 kapt
而不是 implementation
)。
2。注释.
另一个可能的原因:您没有在 Entry
class 中添加 Entity
注释(如 Database
,但您已经有了它。
试试这个
val viewModel = ViewModelProviders.of(this).get(EntryViewModel::class.java)
并在您的应用中 build.gradle
implementation 'android.arch.lifecycle:extensions:1.1.1'