android runtime_error ai_generated true

java.lang.RuntimeException: Cannot create an instance of class com.example.MyViewModel. at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:221) ... Caused by: java.lang.InstantiationException: java.lang.Class<com.example.MyViewModel> has no zero argument constructor

ID: android/viewmodel-factory-required

Also available as: JSON · Markdown · 中文
88%Fix Rate
90%Confidence
1Evidence
2023-04-10First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
Lifecycle 2.5 - 2.7 active
AndroidX Activity 1.7 - 1.8 active

Root Cause

ViewModelProvider.NewInstanceFactory is used but the ViewModel class has a parameterized constructor, requiring a custom ViewModelProvider.Factory or Hilt/AndroidViewModel.

generic

中文

使用了 ViewModelProvider.NewInstanceFactory,但 ViewModel 类具有参数化构造函数,需要自定义 ViewModelProvider.Factory 或 Hilt/AndroidViewModel。

Official Documentation

https://developer.android.com/topic/libraries/architecture/viewmodel/viewmodel-factories

Workarounds

  1. 95% success Create a custom ViewModelProvider.Factory: 'class MyViewModelFactory(private val repository: Repository) : ViewModelProvider.Factory { override fun <T : ViewModel> create(modelClass: Class<T>): T { return MyViewModel(repository) as T } }' and pass it to viewModels(): 'val viewModel: MyViewModel by viewModels { MyViewModelFactory(repository) }'
    Create a custom ViewModelProvider.Factory: 'class MyViewModelFactory(private val repository: Repository) : ViewModelProvider.Factory { override fun <T : ViewModel> create(modelClass: Class<T>): T { return MyViewModel(repository) as T } }' and pass it to viewModels(): 'val viewModel: MyViewModel by viewModels { MyViewModelFactory(repository) }'
  2. 80% success Use AndroidViewModel if the ViewModel needs Application context: 'class MyViewModel(application: Application) : AndroidViewModel(application)' and use by viewModels() without factory.
    Use AndroidViewModel if the ViewModel needs Application context: 'class MyViewModel(application: Application) : AndroidViewModel(application)' and use by viewModels() without factory.

中文步骤

  1. Create a custom ViewModelProvider.Factory: 'class MyViewModelFactory(private val repository: Repository) : ViewModelProvider.Factory { override fun <T : ViewModel> create(modelClass: Class<T>): T { return MyViewModel(repository) as T } }' and pass it to viewModels(): 'val viewModel: MyViewModel by viewModels { MyViewModelFactory(repository) }'
  2. Use AndroidViewModel if the ViewModel needs Application context: 'class MyViewModel(application: Application) : AndroidViewModel(application)' and use by viewModels() without factory.

Dead Ends

Common approaches that don't work:

  1. 50% fail

    The ViewModel may have null fields, causing NullPointerExceptions when accessed; it's a workaround but not a proper fix.

  2. 50% fail

    The delegate uses NewInstanceFactory by default, which requires a no-arg constructor.