2

Im trying to implement Paging but every time i rotate a screen constructor of view model gets called, thus triggering loadInitial to fetch new data from network in my DataSource class.Help appreciated

// ViewModel
def lifecycle_version = "2.2.0"
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
// LiveData
implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"

In my activity oncreate:

TopRatedResultViewModel viewModel =   ViewModelProvider.AndroidViewModelFactory.getInstance(getApplication()).create(TopRatedResultViewModel.class);

View model:

public class TopRatedResultViewModel extends AndroidViewModel {
private Top_Rated_Results_Repository repository;

public TopRatedResultViewModel(@NonNull Application application) {
    super(application);
    Log.d("moviedatabaselog", "TopRatedResultViewModel ");
    repository = new Top_Rated_Results_Repository(application);

}

public LiveData<PagedList<Top_Rated_Result>> getTopRatedResultsPagedList() {
    return repository.getTopRatedResultsPagedList();
}

I was following this tutorial Android paging with retrofit but here deprecated ViewModelProviders.of is used and when i test it after screen rotation constructor dont get called.

Nikola Srdoč
  • 311
  • 4
  • 14
  • 1
    have you added configchanges in manifest for that particular activity, if not then add, android:configChanges="orientation|screenSize" – Ashish Sharma Jun 06 '20 at 04:39
  • 1
    @AshishSharma The ViewModel class allows data to survive configuration changes.So even though activity onDestroy() and onCreate() happens on configuration change, the instance of ViewModel doesn’t get destroyed or garbage collected. You should check out jetpack architecture components... – Nikola Srdoč Jun 06 '20 at 05:58

1 Answers1

7

You should never be calling through to the factory's create() method yourself - this will ignore any previously created ViewModel and always create a new instance rather than only creating one instance and reusing it every time you retrieve the instance.

Instead, you should be following the documentation and using ViewModelProvider:

// By passing in your Activity/Fragment as the ViewModelStoreOwner
// ViewModelProvider is able to retrieve already existing ViewModels
// Rather than create a new one each time
ViewModelProvider viewModelProvider = new ViewModelProvider(this);

// Then you call get() on your ViewModelProvider to get the instance,
// only creating one if one doesn't already exist
TopRatedResultViewModel viewModel = viewModelProvider.get(TopRatedResultViewModel.class);
ianhanniballake
  • 191,609
  • 30
  • 470
  • 443
  • if i use it like that i get the following error: Caused by: java.lang.InstantiationException: java.lang.Class has no zero argument constructor .Im extending AndroidView model cause i need context for my database which is passed trough the constructor.Thanks for the create() hint. – Nikola Srdoč Jun 06 '20 at 05:17
  • 1
    As per the [Lifecycle 2.2.0 release notes](https://developer.android.com/jetpack/androidx/releases/lifecycle#2.2.0), you need to upgrade to `Fragment 1.2.0` or higher if you want to be able to use `AndroidViewModel` with the `ViewModelProvider` constructor by default. Otherwise you can pass the `AndroidViewModelFactory` in as the second parameter to the `ViewModelProvider` constructor. – ianhanniballake Jun 06 '20 at 05:24