Im neuen Projekt kann keine Instanz der Klasse ViewModel erstellt werden
Ich habe zwei verschiedene Projekte. Im ersten verwende ich ViewModel mit meiner Aktivitäts- und Raumdatenbank. Funktioniert alles. Dann habe ich gerade ein neues Projekt für verschiedene Zwecke erstellt und dort instanziiere ich ViewModel auf die gleiche Weise, aber meine App stürzt mit diesem Fehler ab:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example/com.example.MainActivity}: java.lang.RuntimeException: Cannot create an instance of class com.example.MainViewModel
at android.app.ActivityThread.performLaunchActivity(Unknown Source:591)
at android.app.ActivityThread.handleLaunchActivity(Unknown Source:36)
at android.app.servertransaction.LaunchActivityItem.execute(Unknown Source:57)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(Unknown Source:99)
at android.app.servertransaction.TransactionExecutor.execute(Unknown Source:34)
at android.app.ActivityThread$H.handleMessage(Unknown Source:36) at android.os.Handler.dispatchMessage(Unknown Source:21) at android.os.Looper.loop(Unknown Source:207) at android.app.ActivityThread.main(Unknown Source:107) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(Unknown Source:11)
at com.android.internal.os.ZygoteInit.main(Unknown Source:274)
Caused by: java.lang.RuntimeException: Cannot create an instance of class com.example.MainViewModel
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.kazguiu.MainActivity.applyAdapterAndViewModel(MainActivity.kt:37) at com.kazguiu.MainActivity.onCreate(MainActivity.kt:25) at android.app.Activity.performCreate(Unknown Source:16) at android.app.Activity.performCreate(Unknown Source:1) at android.app.Instrumentation.callActivityOnCreate(Unknown Source:3) at android.app.ActivityThread.performLaunchActivity(Unknown Source:368) at android.app.ActivityThread.handleLaunchActivity(Unknown Source:36) at android.app.servertransaction.LaunchActivityItem.execute(Unknown Source:57) at android.app.servertransaction.TransactionExecutor.executeCallbacks(Unknown Source:99) at android.app.servertransaction.TransactionExecutor.execute(Unknown Source:34) at android.app.ActivityThread$H.handleMessage(Unknown Source:36)
at android.os.Handler.dispatchMessage(Unknown Source:21)
at android.os.Looper.loop(Unknown Source:207)
at android.app.ActivityThread.main(Unknown Source:107)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(Unknown Source:11) at com.android.internal.os.ZygoteInit.main(Unknown Source:274) Caused by: java.lang.InstantiationException: java.lang.Class<com.example.MainViewModel> has no zero argument constructor at java.lang.Class.newInstance(Native Method) at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:219)
Ich instanziiere ViewModel in einer Aktivität wie dieser:
private lateinit var mainViewModel: MainViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
applyAdapterAndViewModel()
}
private fun applyAdapterAndViewModel() {
mainViewModel = ViewModelProvider(this).get(MainViewModel::class.java)
}
Mein ViewModel:
class MainViewModel(application: Application) : AndroidViewModel(application) {
private val exampleDao = Database.getDatabase(application).exampleDao()
private val repository = Repository(exampleDao)
fun getSubjects() = repository.getSubjects()
fun addSubjects(subject: Subjects) = viewModelScope.launch(Dispatchers.IO) {
repository.addSubject(subject)
}
}
Diese Art der Verwendung von ViewModel ist dieselbe wie in meinem vorherigen Projekt. Der einzige Unterschied besteht darin, dass ich in meinem aktuellen Gradle zwei zusätzliche Abhängigkeiten habe:
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.2.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0'
Wenn ich sie lösche, erkennt Android Studio ViewModelProvider nicht, aber ich habe diese Abhängigkeiten in meinen vorherigen Projekten überhaupt nicht und verwende LiveData und ViewModel dort absolut gleich (auch die Importe sind gleich). Also, was soll ich tun?
Antworten
Ihr ViewModel erfordert ein Argument, application: Application
das nur mithilfe einer ViewModelFactory wie folgt bereitgestellt werden kann:
ViewModelFactory
class MainViewModelFactory(
private val application: Application
) : ViewModelProvider.Factory {
@Suppress("unchecked_cast")
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(MainViewModel::class.java)) {
return MainViewModel(application) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
}
Hauptaktivität
private fun applyAdapterAndViewModel() {
// Not so kotlinic
mainViewModel = ViewModelProvider(this,MainViewModelFactory(application)).get(MainViewModel::class.java)
}
Auch in MainActivity, ersetzen private lateinit var mainViewModel: MainViewModel
mit
private val viewModel by viewModels<MainViewModel> {
MainViewModelFactory(application) }