无法创建 ViewModel 的实例 class

Cannot create instance of ViewModel class

我在 MainActivity 的 onCreate 方法中执行此操作

journalViewModel = new ViewModelProvider(this).get(JournalViewModel.class);

我的 ViewModel 如下:

public class JournalViewModel extends AndroidViewModel {

    public JournalViewModel(@NonNull Application application) {
        super(application);
        repository = new JournalRepository(application);
        journals = repository.getAllJournals();
    }
}

但是,我收到了这一行的错误,

journalViewModel = new ViewModelProvider(this).get(JournalViewModel.class);

说,

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.diaryapp/com.example.diaryapp.MainActivity}: java.lang.RuntimeException: Cannot create an instance of class com.example.diaryapp.JournalViewModel

据我所知,ViewModel 中的构造函数除了我的代码中的参数外不应有任何其他参数,并且构造函数和 class 都应为 public.

然而,在我的错误日志中,我得到了错误:

java.lang.InstantiationException: java.lang.Class<com.example.diaryapp.JournalViewModel> has no zero argument constructor

完整的错误日志如下:

2020-03-23 21:37:18.986 8632-8632/com.example.diaryapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.diaryapp, PID: 8632
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.diaryapp/com.example.diaryapp.MainActivity}: java.lang.RuntimeException: Cannot create an instance of class com.example.diaryapp.JournalViewModel
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2946)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3081)
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1831)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:201)
    at android.app.ActivityThread.main(ActivityThread.java:6823)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)
 Caused by: java.lang.RuntimeException: Cannot create an instance of class com.example.diaryapp.JournalViewModel
    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.example.diaryapp.MainActivity.onCreate(MainActivity.java:40)
    at android.app.Activity.performCreate(Activity.java:7224)
    at android.app.Activity.performCreate(Activity.java:7213)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1272)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2926)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3081) 
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) 
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1831) 
    at android.os.Handler.dispatchMessage(Handler.java:106) 
    at android.os.Looper.loop(Looper.java:201) 
    at android.app.ActivityThread.main(ActivityThread.java:6823) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873) 
 Caused by: java.lang.InstantiationException: java.lang.Class<com.example.diaryapp.JournalViewModel> 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.example.diaryapp.MainActivity.onCreate(MainActivity.java:40) 
    at android.app.Activity.performCreate(Activity.java:7224) 
    at android.app.Activity.performCreate(Activity.java:7213) 
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1272) 
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2926) 
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3081) 
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) 
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1831) 
    at android.os.Handler.dispatchMessage(Handler.java:106) 
    at android.os.Looper.loop(Looper.java:201) 
    at android.app.ActivityThread.main(ActivityThread.java:6823) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873) 

不确定 Java,但这在 Kotlin 中对我有用。

你需要定义一个ViewModelProvidor.Factory:

class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    viewModelFactory.setApplication(application)
    val journalViewModel = ViewModelProvider(this, viewModelFactory).get(JournalViewModel::class.java)
    }
}

object viewModelFactory : ViewModelProvider.Factory {
    lateinit var app : Application

    fun setApplication(application: Application) {
        app = application
    }
    override fun <T : ViewModel?> create(modelClass: Class<T>): T {
        return JournalViewModel(app) as T
    }

}

我在 this 答案的帮助下开始工作。

这是我所做的,

JournalFactory.java

public class JournalFactory extends ViewModelProvider.NewInstanceFactory {
    private Application application;

    public JournalFactory(@NonNull Application application) {
        this.application = application;
    }

    @NonNull
    @Override
    public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
        if (modelClass == JournalViewModel.class)
            return (T) new JournalViewModel(application);
        return null;
    }
}

onCreate() method of MainActivity.java

journalViewModel = new ViewModelProvider(this, new JournalFactory(getApplication())).get(JournalViewModel.class);

您应该获得 JournalViewModel 如:

journalViewModel = new ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory.getInstance(this.getApplication())).get(JournalViewModel.class);  

而不是

journalViewModel = new ViewModelProvider(this).get(JournalViewModel.class);