Search code examples
androidandroid-livedataandroid-architecture-componentsandroid-mvvm

Why does ViewModelProvider creates new instance of view model on screen rotation?


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.


Solution

  • 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);