Reputation: 2862
I am trying to add Room database with Android ViewModel. I followed this link for the same https://codelabs.developers.google.com/codelabs/android-room-with-a-view/#13
I am getting an exception :
Caused by: java.lang.RuntimeException: Cannot create an instance of class com.example.dailyfaithapp.ViewModels.FavouritesViewModel
I checked some questions and answers on SO, but none working for me.
Here is my view model
public class FavouritesViewModel extends ViewModel {
public FavouriteRepository mRepository;
public LiveData<List<Favourites>> mAllFavourites;
public FavouritesViewModel (Application application) {
mRepository = new FavouriteRepository(application);
mAllFavourites = mRepository.getmAllFavourites();
}
public LiveData<List<Favourites>> getmAllFavourites() { return mAllFavourites; }
public void insert(Favourites favourites) { mRepository.insertFavourite(favourites); }
}
I also tried to Call View model using view model factory but did not work here it is
public class FavouritesViewModelFactory implements ViewModelProvider.Factory {
private Application mApplication;
private String mParam;
public FavouritesViewModelFactory(Application application) {
mApplication = application;
}
@Override
public <T extends ViewModel> T create(Class<T> modelClass) {
return (T) new FavouritesViewModel(mApplication);
}
}
I am creating an instance like this after trying many options following SO:
favouritesViewModel = new ViewModelProvider(this,
new ViewModelProvider.NewInstanceFactory()).get(FavouritesViewModel.class);
Here is my gradle
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation 'com.wdullaer:materialdatetimepicker:4.2.3'
implementation 'com.jaeger.statusbarutil:library:1.4.0'
implementation 'androidx.viewpager2:viewpager2:1.1.0-alpha01'
implementation "com.github.skydoves:balloon:1.1.5"
implementation 'com.afollestad.material-dialogs:core:3.3.0'
annotationProcessor 'org.projectlombok:lombok:1.18.12'
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
// Test helpers
testImplementation "androidx.room:room-testing:$room_version"
Please help. Thank you.
Upvotes: 6
Views: 11359
Reputation: 11
You can try this. `
import androidx.lifecycle.AndroidViewModel;
public class FavouritesViewModel extends AndroidViewModel {
public FavouriteRepository mRepository;
public LiveData<List<Favourites>> mAllFavourites;
public FavouritesViewModel(Application application) {
super(application)
mRepository = new FavouriteRepository(application);
mAllFavourites = mRepository.getmAllFavourites();
}
public LiveData<List<Favourites>> getmAllFavourites() {
return mAllFavourites;
}
public void insert(Favourites favourites) {
mRepository.insertFavourite(favourites);
}
}
`
Now when you want to create an instance of this you can do something like this.
FavouritesViewModel viewModel = new ViewModelProvider
.AndroidViewModelFactory(this.getApplication())
.create(FavouritesViewModel.class);
Upvotes: 1
Reputation: 97
Your ViewModel needs a ViewModel factory
class to instantiate.
I code in Kotlin and I also faced the same problem the below link provides the answer but in kotlin.
https://codelabs.developers.google.com/codelabs/kotlin-android-training-view-model/#7
For Additional Info check this:
EDIT This is my view model factory class of one of my projects
class AccountspageViewModelFactory
(
private val dataSource: accountDao,
private val application: Application
) : ViewModelProvider.Factory {
@Suppress("unchecked_cast")
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(AccountspageViewModel::class.java)) {
return AccountspageViewModel(dataSource,application) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
}
and this is how I instantiated it in fragment
val application = requireNotNull(this.activity).application
val dataSource = accountsdatabase.getInstance(application)?.accountdao
val viewModelFactory = dataSource?.let { AccountspageViewModelFactory(it,application) }
val viewModel =
ViewModelProviders.of(this, viewModelFactory).get(AccountspageViewModel::class.java)\
Change it according to your project but this is in kotlin
Upvotes: 1
Reputation: 663
You should create the instance of ViewModel like this
favouritesViewModel = new ViewModelProvider(this,
new FavouritesViewModelFactory()).get(FavouritesViewModel.class);
Or also you could use
favouritesViewModel = ViewModelProviders.of(this,
new FavouritesViewModelFactory()).get(FavouritesViewModel.class)
hope this helps you.
Upvotes: 0