[英]Android LiveData - how to reuse the same ViewModel on different activities?
示例ViewModel:
public class NameViewModel extends ViewModel {
// Create a LiveData with a String
private MutableLiveData<String> mCurrentName;
public MutableLiveData<String> getCurrentName() {
if (mCurrentName == null) {
mCurrentName = new MutableLiveData<>();
}
return mCurrentName;
}
}
主要活动:
mModel = ViewModelProviders.of(this).get(NameViewModel.class);
// Create the observer which updates the UI.
final Observer<String> nameObserver = textView::setText;
// Observe the LiveData, passing in this activity as the LifecycleOwner and the observer.
mModel.getCurrentName().observe(this, nameObserver);
我想调用mModel.getCurrentName().setValue(anotherName);
在第二个活动中,并使MainActivity接收更改。 那可能吗?
当你调用ViewModelProviders.of(this)
,实际上创建/保留ViewModelStore
这势必会this
,所以不同的活动有不同的ViewModelStore
每个ViewModelStore
创建的不同实例ViewModel
使用给定的工厂,所以你不能有不同ViewModelStore
中的ViewModel
相同实例。
但是,您可以通过传递充当单例工厂的自定义ViewModel工厂的单个实例来实现此目的,因此它将始终在不同的活动之间传递相同的ViewModel
实例。
例如:
public class SingletonNameViewModelFactory extends ViewModelProvider.NewInstanceFactory {
NameViewModel t;
public SingletonNameViewModelFactory() {
// t = provideNameViewModelSomeHowUsingDependencyInjection
}
@Override
public NameViewModel create(Class<NameViewModel> modelClass) {
return t;
}
}
因此,您需要使SingletonNameViewModelFactory
单身(例如,使用Dagger)并像这样使用它:
mModel = ViewModelProviders.of(this,myFactory).get(NameViewModel.class);
注意:
在不同范围之间保留ViewModel
是一种反模式。 强烈建议保留您的数据层对象(例如,使您的DataSource或Repository单例),并在不同范围(活动)之间保留数据。
阅读此文章的详细信息。
当使用ViewModelProviders获取视图模型时,您将以生命周期所有者MainActivity的身份进行传递,这将为该活动提供视图模型。 在第二个活动中,您将获得另一个ViewModel实例,这是您的第二个活动。 第二个模型将具有第二个实时数据。
您可以做的是将数据维护在不同的层(例如存储库)中,该层可能是单例,这样您就可以使用相同的视图模型。
public class NameViewModel extends ViewModel {
// Create a LiveData with a String
private MutableLiveData<String> mCurrentName;
public MutableLiveData<String> getCurrentName() {
if (mCurrentName == null) {
mCurrentName = DataRepository.getInstance().getCurrentName();
}
return mCurrentName;
}
}
//SingleTon
public class DataRepository
private MutableLiveData<String> mCurrentName;
public MutableLiveData<String> getCurrentName() {
if (mCurrentName == null) {
mCurrentName = new MutableLiveData<>();
}
return mCurrentName;
}
//Singleton code
...
}
只需创建ViewModel的实例,在本例中为NameViewModel
您的ViewModel Factory就像
class ViewModelFactory : ViewModelProvider.NewInstanceFactory() {
override fun <T : ViewModel?> create(modelClass: Class<T>) =
with(modelClass){
when {
isAssignableFrom(NameViewModel::class.java) -> NameViewModel.getInstance()
else -> throw IllegalArgumentException("Unknown viewModel class $modelClass")
}
} as T
companion object {
private var instance : ViewModelFactory? = null
fun getInstance() =
instance ?: synchronized(ViewModelFactory::class.java){
instance ?: ViewModelFactory().also { instance = it }
}
}
}
还有你的ViewModel
class NameViewModel : ViewModel() {
//your liveData objects and many more...
companion object {
private var instance : NameViewModel? = null
fun getInstance() =
instance ?: synchronized(NameViewModel::class.java){
instance ?: NameViewModel().also { instance = it }
}
}
}
现在,您可以使用ViewModelProviders
来获取要在任何活动中使用的相同ViewModel实例
ViewModelProviders.of(this, ViewModelFactory.getInstance()).get(NameViewModel::class.java)
要么
创建扩展功能以便于访问
fun <T : ViewModel> AppCompatActivity.getViewModel(viewModelClass: Class<T>) =
ViewModelProviders.of(this, ViewModelFactory.getInstance()).get(viewModelClass)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.