androidkotlinruntime-errorandroid-appcompatandroid-viewmodel

Runtime error while running my app IllegalArgumentException: No initializer set for given class


java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.mikaai/com.example.mikaai.assistant.Assistantactivity}: 
java.lang.IllegalArgumentException: No initializer set for given class com.example.mikaai.assistant.AssistantViewmodel

this is the main error i am getting, the application has been build successfully but while i am trying to start activity in application it crashes and this is the error it shows. i am new to android so i am having hard to understand it. AssistantViewmodel have initializer but it says it dont. please help me if u know anything and guide me in solving this.

i tried to recreate the initializer and it still acts same. i tried to run app on smaller device with lower android and it didnt work either.

package com.example.mikaai.assistant

import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.MutableLiveData
import com.example.mikaai.data.Assistant
import com.example.mikaai.data.AssistantDao
import kotlinx.coroutines.*

class AssistantViewmodel (
    val database: AssistantDao,
            application: Application) :AndroidViewModel(application)
{
                private var viewModeJob = Job()

    override fun onCleared() {
        super.onCleared()
        viewModeJob.cancel()
    }
//initializer
    init {
        initializeCurrentMessage()
    }

    private val uiScope = CoroutineScope(Dispatchers.Main + viewModeJob)

    private var curreMessage = MutableLiveData<Assistant?>()
    val messages = database.getALLMessages()



    private fun initializeCurrentMessage() {
        uiScope.launch { curreMessage.value = getCurrentMessageFromDatabase() }
    }

    private suspend fun getCurrentMessageFromDatabase(): Assistant?{
        return withContext(Dispatchers.IO){
            var message = database.getCurrentMessage()
            if(message?.assistant_message== "DEFAULT_MESSAGE" || message?.human_message == "DEFAULT_MESSAGE")
            {
                message = null
            }
            message
        }

    }

    fun sendMessageToDatabase(assistantMessage: String, humanMessage: String){
        uiScope.launch {
            val newAssistant= Assistant()
            newAssistant.assistant_message = assistantMessage
            newAssistant.human_message = humanMessage
            insert(newAssistant)
            curreMessage.value=getCurrentMessageFromDatabase()

        }
    }


    private suspend fun insert(message: Assistant){
        withContext(Dispatchers.IO){
            database.insert(message)
        }
    }


    private suspend fun update(message: Assistant){
        withContext(Dispatchers.IO){
            database.update(message)
        }
    }

    fun onClear()
    {
        uiScope.launch { clear()
            curreMessage.value= null}
    }

    private suspend fun clear(){
        withContext(Dispatchers.IO){
            database.clear()
        }
    }

}

Solution

  • The problem is with the way you try to get the view model in activity:

    assistantViewModel =
        ViewModelProvider(
            this, viewModelFactory {  }
        ).get(AssistantViewmodel::class.java)
    

    You are using empty factory, so it throws the IllegalArgumentException when it can't find any initializers.

    Since you already have a factory class for view model (AssistantViewmodelFactory), you can use it instead of viewModelFactory { }. Alternatively you can add initializer to the anonymous view model factory like this:

    viewModelFactory { 
        addInitializer(AssistantViewmodel::class) { 
            AssistantViewmodel(dataSoure, application)
        }
    }
    

    After reading your code again, I suspect I know how you got here: your factory variable is called ViewModelFactory with capital first letter. At the same time there is a method from lifecycle library called viewModelFactory with small first letter. One typo and one import later you get very confusing behavior.