许多 ViewModel 实例,如何解决?
Many instances of ViewModel, how to fix it?
我通过 this example:
创建了 ViewModelFactory
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());
}
}
在 Activity 中,我创建了一个 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);
}
}
然后我想在片段中使用 MyViewModel 并按照 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);
...
}
}
和
public class Fragment2 extends Fragment {
...
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
myViewModel = ViewModelProviders.of(this, ViewModelFactory.getInstance(getActivity().getApplication())).get(MyViewModel.class);
...
}
}
问题是在创建片段时,创建了一个新的 MyViewModel 实例(我在日志中看到这个,在 MyViewModel 构造函数中,我显示 "New MyViewModel Instance Created")。随着每个新片段的打开,我在日志中看到 "New MyViewModel Instance Created".
请帮我了解如何解决这个问题?
您正在使用 ViewModelProviders.of(this, ...)
。这意味着您需要一个与该特定 Fragment 关联的 ViewModel 实例。
如果您希望 ViewModel 实例与 Activity 关联,您应该在片段中使用 ViewModelProviders.of(requireActivity(), ...)
。
我通过 this example:
创建了 ViewModelFactorypublic 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());
}
}
在 Activity 中,我创建了一个 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);
}
}
然后我想在片段中使用 MyViewModel 并按照 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);
...
}
}
和
public class Fragment2 extends Fragment {
...
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
myViewModel = ViewModelProviders.of(this, ViewModelFactory.getInstance(getActivity().getApplication())).get(MyViewModel.class);
...
}
}
问题是在创建片段时,创建了一个新的 MyViewModel 实例(我在日志中看到这个,在 MyViewModel 构造函数中,我显示 "New MyViewModel Instance Created")。随着每个新片段的打开,我在日志中看到 "New MyViewModel Instance Created".
请帮我了解如何解决这个问题?
您正在使用 ViewModelProviders.of(this, ...)
。这意味着您需要一个与该特定 Fragment 关联的 ViewModel 实例。
如果您希望 ViewModel 实例与 Activity 关联,您应该在片段中使用 ViewModelProviders.of(requireActivity(), ...)
。