Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot create an instance of class - ViewModel

I'm following an example of google, the example is in java but when I rewrite it in kotlin I can not instantiate the class. I am learning viewmodel. I have a lot of doubt if I messed up the syntax of my kotlin code.

https://github.com/googlecodelabs/android-room-with-a-view

Error class MainActivity: AppCompatActivity() {

//    private lateinit var mWordViewModel: WordViewModel //not works
    private var mWordViewModel: WordViewModel? = null //not works
    private var wordListAdapter: WordListAdapter?= null

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

        try {
            mWordViewModel = ViewModelProviders.of(this@MainActivity).get(WordViewModel::class.java)
        }catch (e: Exception){
            e.printStackTrace()
        }

...

class WordViewModel(application: Application): AndroidViewModel(application) {

//    super(application)

    private var mRepository: WordRepository? = null
    private var mAllWords: LiveData<List<Word>>? = null

    init {
        mRepository = WordRepository(application)
        mAllWords = mRepository?.getAllWords()
    }

...

class WordRepository(application: Application) {

    private var mWordDao: WordDao? = null
    private var mAllWords: LiveData<List<Word>>? = null

    init {
        val db = WordRoomDatabase.getDatabase(application)
        mWordDao = db.wordDao()
        mAllWords = mWordDao!!.getAlphabetizeWords()
    }

...

@Database(entities = arrayOf(Word::class), version = 1)
abstract class WordRoomDatabase: RoomDatabase(){

    abstract fun wordDao(): WordDao

    companion object {
        @JvmStatic
        private var INSTANCE: WordRoomDatabase? = null

        fun getDatabase(context: Context): WordRoomDatabase {
            if (INSTANCE == null) {
                synchronized(WordRoomDatabase::class.java) {
                    if (INSTANCE == null) {
                        INSTANCE = Room.databaseBuilder(context.applicationContext, WordRoomDatabase::class.java, "word_database")
                                .fallbackToDestructiveMigration()
                                .addCallback(sRoomDatabaseCallback)
                                .build()
                    }
                }
            }
            return INSTANCE!!
        }
like image 908
FlipNovid Avatar asked Jun 21 '18 12:06

FlipNovid


People also ask

What is AndroidViewModel?

The AndroidViewModel class is a subclass of ViewModel and similar to them, they are designed to store and manage UI-related data are responsible to prepare & provide data for UI and automatically allow data to survive configuration change.

What is the use of ViewModel class?

The ViewModel class is designed to store and manage UI-related data in a lifecycle conscious way. The ViewModel class allows data to survive configuration changes such as screen rotations.

What is ViewModelProvider factory?

ViewModelProvider. Factory which may create AndroidViewModel and ViewModel , which have an empty constructor. Simple factory, which calls empty constructor on the give class. Implementations of Factory interface are responsible to instantiate ViewModels.


2 Answers

@zunjae

Errors

1 - Syntax code koltin.

2 - Project configuration.

class MainActivity: AppCompatActivity() {
mWordViewModel = ViewModelProviders.of(this@MainActivity).get(WordViewModel(application)::class.java)

...

class WordViewModel constructor (application: Application):  AndroidViewModel(application){

...

class WordRepository constructor(application: Application) {

...

add app build.gradle

apply plugin: 'kotlin-kapt'

kapt "android.arch.lifecycle:extensions:$rootProject.archLifecycleVersion"
kapt "android.arch.persistence.room:compiler:$rootProject.roomVersion"
like image 135
FlipNovid Avatar answered Oct 12 '22 21:10

FlipNovid


I had the same issue, in JAVA though. My issue was solved with using the ViewModelFactory as follows:

public class MyViewModelFactory implements ViewModelProvider.Factory {
    private Application mApplication;



    public MyViewModelFactory(Application application) {
        mApplication = application;

    }
    @Override
    public <T extends ViewModel> T create(Class<T> modelClass) {
        return (T) new BookViewModel(mApplication);
    }

And where you call the ViewModel, change it to:

mBookViewModel = new ViewModelProvider(this, new MyViewModelFactory
                (this.getApplication())).get(BookViewModel.class);

You can check this link for this issue from the tutorial's Github issues page: https://github.com/googlecodelabs/android-room-with-a-view/issues

like image 29
Shubam Bharti Avatar answered Oct 12 '22 19:10

Shubam Bharti