Reputation: 53
I'm trying to make a simple ToDoList application using the recyclerview and the room library. I'm following the android developers codelab on using room and mvvm architecture and I seem to have hit a stump. I have set up every layer of the application but I'm getting an error when trying to instantiate the ViewModel using the ViewModelProvider. Here is the code from my ViewModel class.
class TaskViewModel(application: Application) : AndroidViewModel(application) {
private val repository : TaskRepository
val allTasks : LiveData<List<Task>>
init{
val tasksDao = TaskRoomDatabase.getDatabase(application)!!.taskDao()
repository = TaskRepository(tasksDao)
allTasks = repository.allTasks
}
fun saveTask(task : Task) = viewModelScope.launch(Dispatchers.IO){
repository.saveTask(task)
}
}
And here is the code from my MainFragment from which I'm trying to initialize the ViewModel:
class MainFragment() : Fragment() {
private lateinit var recyclerView : RecyclerView
private lateinit var sharedTaskViewModel : TaskViewModel
private lateinit var fab : FloatingActionButton
var tasks = emptyList<Task>()
private lateinit var adapter : MainRecyclerViewAdapter
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val view = inflater.inflate(R.layout.fragment_main, container, false)
fab = view.findViewById(R.id.floatingActionButton)
//Initialize the recyclerview
recyclerView = view.findViewById(R.id.main_recyclerview)
adapter = MainRecyclerViewAdapter()
recyclerView.adapter = adapter
recyclerView.layoutManager = LinearLayoutManager(view.context)
return view
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
sharedTaskViewModel = ViewModelProvider(this).get(TaskViewModel::class.java)
fab.setOnClickListener {
fragmentManager!!.beginTransaction().apply {
replace(R.id.fl_fragment_main, NewTaskFragment())
commit()
}
}
}
}
When I run the code I get this message:
2020-08-09 11:31:00.734 27860-27860/com.robybp.todolist E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.robybp.todolist, PID: 27860
java.lang.RuntimeException: Cannot create an instance of class com.robybp.todolist.view_models.TaskViewModel
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.robybp.todolist.view.fragments.MainFragment.onViewCreated(MainFragment.kt:45)
Caused by: java.lang.InstantiationException: java.lang.Class<com.robybp.todolist.view_models.TaskViewModel> has no zero argument constructor
at java.lang.Class.newInstance(Native Method)
Please do forgive me if the question may be "Obslite" but i'm just getting familiar with room and mvvm architecture. Thank you for understanding.
Upvotes: 1
Views: 2603
Reputation: 38309
Try replacing:
sharedTaskViewModel = ViewModelProvider(this).get(TaskViewModel::class.java)
with
sharedTaskViewModel = ViewModelProvider.AndroidViewModelFactory(application)
.create(TaskViewModel::class.java)
Upvotes: 3