问题
I made ViewModelFactory by this example:
public class ViewModelFactory extends ViewModelProvider.NewInstanceFactory {
@SuppressLint("StaticFieldLeak")
private static volatile ViewModelFactory INSTANCE;
private final Application application;
public static ViewModelFactory getInstance(Application application) {
if (INSTANCE == null) {
synchronized (ViewModelFactory.class) {
if (INSTANCE == null) {
INSTANCE = new ViewModelFactory(application);
}
}
}
return INSTANCE;
}
private ViewModelFactory(Application application) {
this.application = application;
}
@Override
public <T extends ViewModel> T create(Class<T> modelClass) {
if (modelClass.isAssignableFrom(MyViewModel.class)) {
//noinspection unchecked
return (T) new MyViewModel(
Repository.getInstance(
RemoteDataSource.getInstance(WebService.getInstance().getWebServiceApi()),
LocalDataSource.getInstance(new AppExecutors(), MyDatabase.getInstance(application).myDao())
)
);
}
throw new IllegalArgumentException("Unknown ViewModel class: " + modelClass.getName());
}
}
In Activity, I create an instance of ViewModel:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
Log.d(TAG, "onCreate");
if (savedInstanceState == null) {
myViewModel = ViewModelProviders.of(this, ViewModelFactory.getInstance(this.getApplication())).get(MyViewModel.class);
}
}
Then I want to use MyViewModel in fragments and do as in this example:
public class Fragment1 extends Fragment {
...
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
myViewModel = ViewModelProviders.of(this, ViewModelFactory.getInstance(getActivity().getApplication())).get(MyViewModel.class);
...
}
}
And
public class Fragment2 extends Fragment {
...
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
myViewModel = ViewModelProviders.of(this, ViewModelFactory.getInstance(getActivity().getApplication())).get(MyViewModel.class);
...
}
}
The problem is that when creating fragments, a new instance of MyViewModel is created (I see this in the logs, in the MyViewModel constructor, I display "New MyViewModel Instance Created"). With the opening of each new fragment, I see in the logs "New MyViewModel Instance Created".
Help me please understand how to fix this?
回答1:
You're using ViewModelProviders.of(this, ...)
. This means you want an instance of the ViewModel associated with that particular Fragment.
You should use ViewModelProviders.of(requireActivity(), ...)
in your Fragments if you want the ViewModel instance associated with the Activity.
来源:https://stackoverflow.com/questions/57014586/many-instances-of-viewmodel-how-to-fix-it