0

I am new to viewmodel and room database. I am following a tutorial

https://www.adictosaltrabajo.com/2019/03/04/persistencia-de-datos-en-android-con-room/

But when I run the app I get the error

"Unable to start activity ComponentInfo{com.example.romapp/com.example.romapp.MainActivity}: java.lang.RuntimeException: Cannot create an instance of class com.example.romapp.ViewModel.ContactsViewModel"

this is my viewmodel class

class ContactsViewModel(application: Application) : AndroidViewModel(application) {
    private val repository = ContactsRepository(application)
    val contacts = repository.getContacts()

    fun saveContact(contact: Person) {
        repository.insert(contact)
    }
}

this is my repository

class ContactsRepository(application: Application) {
    private val contactDao: ContactDao? = com.example.romapp.DataBase.ContactsDatabase.getInstance(application)?.contactDao()

    fun insert(contact: Person) {
        if (contactDao != null) InsertAsyncTask(contactDao).execute(contact)
    }

    fun getContacts(): LiveData<List<Person>> {
        return contactDao?.getOrderedAgenda() ?: MutableLiveData<List<Person>>()
    }

    private class InsertAsyncTask(private val contactDao: ContactDao) :
        AsyncTask<Person, Void, Void>() {
        override fun doInBackground(vararg contacts: Person?): Void? {
            for (contact in contacts) {
                if (contact != null) contactDao.insert(contact)
            }
            return null
        }
    }
}

this is my main class create

contactsViewModel = run {
            ViewModelProviders.of(this).get(ContactsViewModel::class.java)
        }

This is what I added to my build.gradle

implementation 'android.arch.persistence.room:runtime:1.1.1'
annotationProcessor 'android.arch.persistence.room:compiler:1.1.1'

implementation "android.arch.lifecycle:extensions:1.1.1"

Any help or suggestion would be great

2 Answers2

0

That's because you are trying to instantiate a viewmodel that needs an argument to provide. you should use ViewModelFactory to instantiate that. for more details see this link

Hamid Sj
  • 983
  • 7
  • 19
0

First, you should initial you repository in this way


class MyRepository (private val api: ApiInterface,private val db:Dao){
     // work with db and Api here
}

Second, your view model should be something like this:


class MyViewModel (private val myRepository: MyRepository) : ViewModel() {
  //work with you reposiroty here... 
}

Finally when you want use your ViewModel instance in ui layer. Write it like this.

 private lateinit var mViewModel : MyViewModel
.
.
.
.
.
.
.
.

 mViewModel = ViewModelProviders.of(this).get(MyViewModel.class);

Now you should be able to use your ViewModel properly.

Faramarz Afzali
  • 726
  • 1
  • 10
  • 24