简体   繁体   English

无法创建类 ViewModel 的实例

[英]Cannot Create Instance Of Class ViewModel

I'm currently working on a countdown app, and whenever I open it, it fails with a message saying Cannot create instance of class com.nailuj29gaming.CountdownViewModel我目前正在开发一个倒计时应用程序,每当我打开它时,它都会失败并显示一条消息,提示Cannot create instance of class com.nailuj29gaming.CountdownViewModel

The stack trace is堆栈跟踪是

    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) 

I know there is a very similar question, this one , but that is target at Java, and my code is written in Kotlin.我知道有一个非常相似的问题,this one ,但那是针对 Java 的,我的代码是用 Kotlin 编写的。 My ViewModel class's text is我的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)
    }
}

I create the ViewModel in the first line of my MainActivity.onCreate() method.我在MainActivity.onCreate()方法的第一行创建了ViewModel The code I used to create it is viewModel = ViewModelProvider(this).get(CountdownViewModel::class.java)我用来创建它的代码是viewModel = ViewModelProvider(this).get(CountdownViewModel::class.java)

My build.gradle file (at least what matters in this question) is我的 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"
}

I tried using a factory, but the ViewModelProviders class is deprecated我尝试使用工厂,但不推荐使用 ViewModelProviders 类弃用

When I used a delegate, the IDE did not give me an error, but the compiler said我用delegate的时候,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

My code is compiled into bytecode built with JVM target 1.8, so this error shouldn't show, right?我的代码被编译成用 JVM 目标 1.8 构建的字节码,所以不应该显示这个错误,对吧?

You need to upgrade to Fragment 1.2.0 or higher, which is what adds a support for the ViewModelProvider constructor as per the Lifecycle 2.2.0 release notes :您需要升级到 Fragment 1.2.0 或更高版本,根据Lifecycle 2.2.0 发行说明,这增加了对ViewModelProvider构造函数的支持:

You can pass a Fragment or FragmentActivity to the new ViewModelProvider(ViewModelStoreOwner) constructor to achieve the same functionality when using Fragment 1.2.0 .您可以将 Fragment 或 FragmentActivity 传递给新的 ViewModelProvider(ViewModelStoreOwner) 构造函数,以在使用Fragment 1.2.0时实现相同的功能。

When using an older version of Fragments (ie, the Fragment 1.1.0 that AppCompat 1.1.0 pulls in), you'll only get the ViewModelProvider$NewInstanceFactory you see in your exception trace, rather than a ViewModel.Factory that supports AndroidViewModel .当使用旧版本的 Fragment(即 AppCompat 1.1.0 引入的 Fragment 1.1.0)时,您只会获得在异常跟踪中看到的ViewModelProvider$NewInstanceFactory ,而不是支持AndroidViewModel的 ViewModel.Factory 。

Therefore you should add an explicit dependency on Fragment 1.3.5 (the current latest):因此,您应该添加对 Fragment 1.3.5(当前最新版本)的显式依赖:

implementation 'androidx.fragment:fragment:1.3.5'

This post helped me, as I was facing a similar issue: https://stackoverflow.com/a/60670866/6030520这篇文章帮助了我,因为我面临着类似的问题: https : //stackoverflow.com/a/60670866/6030520

To address the error you were getting ( 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 ), you can simply add:要解决您遇到的错误( 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 ),您可以简单地添加:

android { 

    ...

    kotlinOptions { jvmTarget = "1.8" }

}

... to your app/build.gradle file. ...到您的 app/build.gradle 文件。

You should consider this line from the stacktrace您应该考虑堆栈跟踪中的这一行

Caused by: java.lang.InstantiationException: java.lang.Class has no zero argument constructor引起:java.lang.InstantiationException:java.lang.Class 没有零参数构造函数

This means you should pass an argument in the constructor when you buildng your viewmodel这意味着您应该在构建viewmodel时在构造函数中传递一个参数

In the link you quoted there is a specific kotlin answer] 1在您引用的链接中有一个特定的 kotlin 答案] 1

EDIT: And also control that you have correctly insta intiated the factory as shown in this response or this other one编辑:还管是否正确斯塔发起的工厂如本响应或其他这样一个

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

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