android - 无法创建类 ViewModel 的实例
问题描述
我目前正在开发一个倒计时应用程序,每当我打开它时,它都会失败并显示一条消息Cannot create instance of class com.nailuj29gaming.CountdownViewModel
堆栈跟踪是
Process: com.nailuj29gaming.countdown.debug, PID: 17800
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.nailuj29gaming.countdown.debug/com.nailuj29gaming.countdown.MainActivity}: java.lang.RuntimeException: Cannot create an instance of class com.nailuj29gaming.countdown.CountdownViewModel
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2750)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2811)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1528)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6316)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:872)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:762)
Caused by: java.lang.RuntimeException: Cannot create an instance of class com.nailuj29gaming.countdown.CountdownViewModel
at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:221)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:187)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
at com.nailuj29gaming.countdown.MainActivity.onCreate(MainActivity.kt:23)
at android.app.Activity.performCreate(Activity.java:6757)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2703)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2811)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1528)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6316)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:872)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:762)
Caused by: java.lang.InstantiationException: java.lang.Class<com.nailuj29gaming.countdown.CountdownViewModel> has no zero argument constructor
at java.lang.Class.newInstance(Native Method)
at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:219)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:187)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
at com.nailuj29gaming.countdown.MainActivity.onCreate(MainActivity.kt:23)
at android.app.Activity.performCreate(Activity.java:6757)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2703)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2811)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1528)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6316)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:872)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:762)
我知道有一个非常相似的问题,this one,但它是针对 Java 的,我的代码是用 Kotlin 编写的。我ViewModel
班的课文是
package com.nailuj29gaming.countdown
import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.launch
class CountdownViewModel(application: Application) : AndroidViewModel(application) {
private val repo: CountdownRepo
val countdowns: LiveData<List<Countdown>>
init {
val countdownDao = AppDatabase.getDatabase(application).countdownDao()
repo = CountdownRepo(countdownDao)
countdowns = repo.countdowns
}
fun insert(countdown: Countdown) = viewModelScope.launch {
repo.insert(countdown)
}
fun delete(countdown: Countdown) = viewModelScope.launch {
repo.delete(countdown)
}
}
我在我的方法ViewModel
的第一行创建。MainActivity.onCreate()
我用来创建它的代码是viewModel = ViewModelProvider(this).get(CountdownViewModel::class.java)
我的 build.gradle 文件(至少在这个问题中很重要)是
apply plugin: 'kotlin-kapt'
dependencies {
def room_version = "2.2.3"
def lifecycle_version = "2.2.0"
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.core:core-ktx:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.13'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation 'com.google.code.gson:gson:2.8.6'
implementation 'androidx.preference:preference:1.1.0'
implementation 'net.steamcrafted:materialiconlib:1.1.5'
implementation 'com.google.android.material:material:1.0.0'
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
implementation "androidx.room:room-ktx:$room_version"
}
我尝试使用工厂,但不推荐使用 ViewModelProviders 类
当我使用委托时,IDE没有给我错误,但是编译器说
Cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6. Please specify proper '-jvm-target' option
我的代码被编译成使用 JVM 目标 1.8 构建的字节码,所以这个错误不应该出现,对吧?
解决方案
您需要升级到 Fragment 1.2.0 或更高版本,这是根据Lifecycle 2.2.0 发行说明ViewModelProvider
添加对构造函数的支持:
您可以将 Fragment 或 FragmentActivity 传递给新的 ViewModelProvider(ViewModelStoreOwner) 构造函数,以在使用Fragment 1.2.0时实现相同的功能。
当使用旧版本的 Fragments(即 AppCompat 1.1.0 引入的 Fragment 1.1.0)时,您只会得到ViewModelProvider$NewInstanceFactory
您在异常跟踪中看到的,而不是支持AndroidViewModel
.
因此,您应该添加对 Fragment 1.3.5(当前最新版本)的显式依赖:
implementation 'androidx.fragment:fragment:1.3.5'
推荐阅读
- android - 内存不足异常问题
- actionscript-3 - TypeError:错误 #1009:无法访问空对象引用的属性或方法。在 AoW_2_fla::MainTimeline/frame1()
- python - Django Admin,可折叠文本框
- python - 在现有文件python中的特定位置插入内容
- azure - 如何在 VSTS CI-Build 中集成 AzSK
- xamarin - Xamarin Android 弹出页面内存泄漏
- android - 我在 android studio 中使用回收器视图,每个项目都有一个可绘制的。如何通过单击特定位置来更改可绘制对象的颜色?
- oracle - 厨师食谱资源如何在完成 oracle setup.exe 完全运行后才运行食谱/资源
- javascript - iOS cordova-plugin-camera 在 PNG 上添加黑色背景
- spark-graphx - 用相同的数据和代码运行GraphX的connectedComponents两次,结果不同