Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I'm trying to create a instance of a ViewModel using Android Architecture Components in my Fragment with Kotlin and I obtain the next error:

E/AndroidRuntime: FATAL EXCEPTION: main
Process: campanoon.cronometrohiit, PID: 3871
java.lang.RuntimeException: Cannot create an instance of class campanoon.cronometrohiit.RoutinesViewModel 
at android.arch.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:153)

My ViewModel:

class RoutinesViewModel(application: Application) : ViewModel() {
private val routineDao = AppDatabase.getDatabase(application).routineDao()
fun generateSimpleList() : List<Routine> {
    routineDao.insertRoutine(Routine(null,"Prueba 1", "00:10","00:30","30:00",3))
    routineDao.insertRoutine(Routine(null,"Prueba 2", "00:15","00:30","15:00",2))
    routineDao.insertRoutine(Routine(null,"Prueba 3", "00:20","00:30","20:00",5))
    return routineDao.getRoutines()

My fragment:

class RoutinesFragment : Fragment() {
private lateinit var routinesViewModel : RoutinesViewModel
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                          savedInstanceState: Bundle?): View? {
    val v : View = inflater.inflate(R.layout.fragment_routines, container, false)
    routinesViewModel= ViewModelProviders.of(this).get(RoutinesViewModel::class.java)
    return v

I don't know what I'm doing wrong :(

If you need to pass in parameter in to constructor of ViewModel you'll need to use ViewModel.Factory

open class RoutinesViewModelFactory(private val application: Application) : ViewModelProvider.Factory {
     override fun <T : ViewModel> create(modelClass: Class<T>): T {
        if (modelClass.isAssignableFrom(RoutinesViewModel::class.java)) {
            return RoutinesViewModel(application) as T
        throw IllegalArgumentException("Unknown ViewModel class")

If you're using dagger for example you'd inject instance of RoutinesViewModelFactory in your fragment

@Inject lateinit var routinesViewModelFactory: RoutinesViewModelFactory

and then retrieve ViewModel instance by calling

routinesViewModel = ViewModelProviders.of(this, RoutinesViewModelFactory).get(RoutinesViewModel::class.java)
                I've tried but I get the following error:     kotlin.UninitializedPropertyAccessException: lateinit property routinesViewModelFactory has not been initialized
– campanoon
                Oct 27, 2018 at 17:02
                That was as an example if you were using Dagger....which sounds like you're not using?  If not, then use whatever DI framework you're using to inject instance of this or at least as test for now create an instance of RoutinesViewModelFactory in your fragment (passing application in constructor)
– John O'Reilly
                Oct 27, 2018 at 17:09
                No, because I am junior in android development and had not done dependency injections. Thanks for your response, you've helped me.
– campanoon
                Nov 15, 2018 at 12:37
                np....but you can also do this without dependency injection...as mentioned you can  if needed just create instance of RoutinesViewModelFactory directly (or though your own service locator/factory etc)
– John O'Reilly
                Nov 15, 2018 at 12:38
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.