Im neuen Projekt kann keine Instanz der Klasse ViewModel erstellt werden

Nov 25 2020

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

1 AndrewChelix Nov 25 2020 at 11:52

Ihr ViewModel erfordert ein Argument, application: Applicationdas 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) }