vibhum mohan
vibhum mohan

Reputation: 35

Not able to get instance of view model class

App name : Scribble, Functionality : Basic Note Taking App Issue : Application is crashing as compiler is not able to get instance of NoteViewModel class says no zero argument constructor

MAIN ACTIVITY :

class MainActivity : AppCompatActivity(), ClickListeners {

lateinit var recyclerView : RecyclerView
lateinit var addButton : FloatingActionButton
lateinit var viewModel : NoteViewModel
lateinit var adapter : NoteViewAdapter


override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    recyclerView = findViewById(R.id.NotesRV)
    addButton = findViewById(R.id.addButton)
    viewModel = ViewModelProvider.AndroidViewModelFactory.getInstance(application).create(NoteViewModel::class.java)

    addButton.setOnClickListener{
         val intent : Intent = Intent(this,AddNoteActivity::class.java)
         startActivity(intent)
    }
    showAllNotes()

}

override fun onNoteClick(note: Note) {
    TODO("Not yet implemented")
}

override fun onDeleteButtonClick(note: Note) {
    TODO("Not yet implemented")
}

override fun onNoteLongClick(note: Note) {
    TODO("Not yet implemented")
}

fun showAllNotes(){
    viewModel.allNotes.observe(this, Observer {list ->
        adapter = NoteViewAdapter(list as ArrayList<Note>,this, this)
        recyclerView.adapter = adapter
        recyclerView.layoutManager = GridLayoutManager(this,2,GridLayoutManager.VERTICAL,false)
    })
}

problem is in this line :

ViewModelProvider.AndroidViewModelFactory.getInstance(application).create(NoteViewModel::class.java)

VIEW MODEL CLASS :

class NoteViewModel (application: Application) : ViewModel() {

 val allNotes: LiveData<List<Note>>
 val repository: NoteRepository

init {

    val dao = NoteDatabase.getDatabase(application).getNotesDao()

    repository = NoteRepository(dao)

    allNotes = repository.allNotes
}

fun insertNote(note: Note) {
 
    viewModelScope.launch(Dispatchers.IO){
        
        repository.insertNote(note)
    }
}

fun deleteNote(note: Note) = viewModelScope.launch(Dispatchers.IO){repository.deleteNote(note)}

fun updateNote(note: Note) = viewModelScope.launch(Dispatchers.IO){repository.updateNote(note)}

LOGCAT :

    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.scribble/com.example.scribble.MainActivity}: java.lang.RuntimeException: Cannot create an instance of class com.example.scribble.model.NoteViewModel
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3635)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3792)
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2210)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loopOnce(Looper.java:201)
    at android.os.Looper.loop(Looper.java:288)
    at android.app.ActivityThread.main(ActivityThread.java:7839)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
 Caused by: java.lang.RuntimeException: Cannot create an instance of class com.example.scribble.model.NoteViewModel
    at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.kt:188)
    at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.kt:238)
    at com.example.scribble.MainActivity.onCreate(MainActivity.kt:31)
    at android.app.Activity.performCreate(Activity.java:8051)
    at android.app.Activity.performCreate(Activity.java:8031)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1329)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3608)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3792) 
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103) 
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2210) 
    at android.os.Handler.dispatchMessage(Handler.java:106) 
    at android.os.Looper.loopOnce(Looper.java:201) 
    at android.os.Looper.loop(Looper.java:288) 
    at android.app.ActivityThread.main(ActivityThread.java:7839) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003) 
 Caused by: java.lang.InstantiationException: java.lang.Class<com.example.scribble.model.NoteViewModel> has no zero argument constructor
    at java.lang.Class.newInstance(Native Method)
    at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.kt:186)
    at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.kt:238) 
    at com.example.scribble.MainActivity.onCreate(MainActivity.kt:31) 
    at android.app.Activity.performCreate(Activity.java:8051) 
    at android.app.Activity.performCreate(Activity.java:8031) 
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1329) 
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3608) 
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3792) 
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103) 
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2210) 
    at android.os.Handler.dispatchMessage(Handler.java:106) 
    at android.os.Looper.loopOnce(Looper.java:201) 
    at android.os.Looper.loop(Looper.java:288) 
    at android.app.ActivityThread.main(ActivityThread.java:7839) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003) 

This is error reason :

Caused by: java.lang.InstantiationException: java.lang.Class<com.example.scribble.model.NoteViewModel> has no zero argument constructor

Tried searching but no idea what to do for this...

Upvotes: 0

Views: 606

Answers (1)

Sasa Arsenovic
Sasa Arsenovic

Reputation: 421

According to developer.android documentation: "If ViewModel class receives dependencies in its constructor, provide a factory that implements the ViewModel.Factory interface. Your ViewModel should have something like this

companion object {
    val Factory: ViewModelProvider.Factory = object : ViewModelProvider.Factory {
        @Suppress("UNCHECKED_CAST")
        override fun <T : ViewModel> create(modelClass: Class<T>, extras: CreationExtras): T {
            val application = checkNotNull(extras[APPLICATION_KEY])
            if (modelClass.isAssignableFrom(NoteViewModel::class.java)) {
                return NoteViewModel(application = application) as T
            }
            throw IllegalArgumentException("Unknown ViewModel class")
        }
    }
}

and you can instantiate your viewModel with:

private val viewModel: NoteViewModel by viewModels { NoteViewModel.Factory }

Upvotes: 2

Related Questions