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()
}
}
}
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.