ViewModel is created again for the fragment

2019-03-29 09:04发布

问题:

I create viewmodel in MainFragment:

 @Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
   ...
    MainViewModel mainViewModel = ViewModelProviders.of(this).get(MainViewModel.class);
   ...
}

When user select item then navigate to Details fragment, this transaction is added to backstack.

 getFragmentManager()
                .beginTransaction()
                .replace(R.id.root, Details.newInstance())
                .addToBackStack(null)
                .commit();

When user press back in Details fragment, everything is ok, but if user rotate device in Details fragment and press back then:

  • new instance of ViewModel is created for MainFragment
  • old instance is still alive ( method onCleared not called)

Is this a bug in ViewModelProviders? How to fix this? In my opinion ViewModel should be restored.

回答1:

This is not really obvious, but when you call addToBackStack, the fragment manager will not destroy your fragment, just stops it, when new replace transaction comes. You basically have two items on the backstack now, both being instances of your Details. Since onDestroy was never called for the first one, its ViewModel's onCleared was never called either.

In your case, simply checking if your fragment is currently in the container (e.g. via FragmentManager.findFragment() and NOT replacing it in such situation, should be enough.



回答2:

You are use link to fragment but need to Activity use:

MainViewModel mainViewModel = ViewModelProviders.of(getActivity()).get(MainViewModel.class);


回答3:

This is a confirmed issue. The fix is available in the AndroidX 1.0.0-alpha2 release. https://issuetracker.google.com/issues/73644080