问题
I've creating a test activity that updates some text in my MyViewModel.
I'd like to observe these changes in a Fragment, but when I use
MyViewModel myViewModel = new ViewModelProvider(this).get(MyViewModel.class);
it gives me a different instance of MyViewModel than that used in the activity, which results in my onChanged()
callback in the fragment not being called.
Only when I modify that same fragment code to
HomeViewModel homeViewModel = new ViewModelProvider(getActivity()).get(HomeViewModel.class);
does the fragment get the same instance of MyViewModel as the activity - so onChanged()
is successfully called.
However, I'm not sure if using getActivity()
as the ViewModelStoreOwner is the proper way of doing things as I haven't seen this in any examples anywhere. I'm wondering if there might be a better ViewModelStoreOwner I should be using in this instance?
回答1:
Having an Activity
which does as little as possible has become a "best practice" for some time now, so the scenario of an Activity
and a Fragment
which need access to the same ViewModel
instance may not be covered by many guides.
But "there is no rule without an exception", and your scenario is similar to the one where an Activity
has two Fragment
s which need to share data.
In this case, one uses the Activity
scope for the ViewModel
to make sure every component will have access to the same instance. See also the section "Share data between fragments" in the View Model Overview at developer.android.com
回答2:
I'm wondering if there might be a better ViewModelStoreOwner I should be using in this instance?
You should use activity
instance for sharing the same instance among fragments in the same activity.
Both Activity and Fragment implements their own ViewModelStoreOwner interface and implements the getViewModelStore()
method. getViewModelStore()
provide the ViewModelStore
instance which is used to store the viewmodel
objects, created by the ViewModelProvider
.
Note: ComponentActivity implements the ViewModelStoreOwner
interface and FragmentActivity
(parent of AppCompatActivity) inherits the implementation.
So both Activity and Fragment have specific implementation for the ViewModelStoreOwner
interface methods and store the viewmodel instance as per the lifecycle
of the objects(including the configuration changes).
Since fragments belong to activity get the same activity instance so using the getActivity()
will result in using the ViewModelStoreOwner
object of the activity. To share the objects among fragments, simply use the activity instance for creating ViewModelProvider
which will use the same ViewModelStoreOwner
in all fragments hence will return the persisted object of viewmodel
(if created before).
回答3:
I think you are getting error not because of your ViewModel class. I erased all the codes except the constructor and just kept a simple class. It works fine. If you are following MVVM pattern then, the you may get error because of the database implementation or you may check the repository.
来源:https://stackoverflow.com/questions/61373456/what-viewmodelstoreowner-to-use-for-viewmodelprovider-in-fragment