所以,我刚刚开始尝试使用LiveData
- 我正在忙于一个新项目,我正在使用ViewModel
以及LiveData
- 一些{{1}我用来获取数据的服务,它们不带参数并返回一些数据。
使用RESTFul
的MVVM范例的典型设置看起来很像:
LiveData
现在,当我们离开此活动,并通过使用Intent或其他方式进入新活动,而不是按后退按钮(因此,public class MyActivity extends AppCompatActivity {
public void onCreate(Bundle savedInstanceState) {
MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class);
model.getUsers().observe(this, users -> {
// update UI
});
}
}
未被调用) - 然后回到finalize
- 我们当然不会再次获取MyActivity
,因为我们仍然应该拥有该数据。
但是,如果我们确实想要再次获取它们呢?
根据我所看到的,正确执行此操作的唯一方法似乎是在users
getUsers()
对象上调用“setValue”
这样的事情:
LiveData
public class MyActivity extends AppCompatActivity {
public void onResume() {
viewModel.setActive(true);
}
}
看起来像这样:
ViewModel
我决定这样做的一个原因是因为Google不希望我们这样做:
private final MutableLiveData<Boolean> activeLiveData = new MutableLiveData<>();
ViewModel(ViewModelRepo repo){
this.repo = repo;
results = Transformations.switchMap(activeLiveData, active ->{
if(active){
return repo.getUsers();
}else {
return AbsentLiveData.create(); //"Null live data"
}
});
}
LiveData<Users>> getUsers() {
return results;
}
//This could be called "update" with no params
void setActive(boolean active) {
activeLiveData.setValue(active);
}
出于这个原因:
如果这是实现,则UI需要取消注册 之前的LiveData并每次重新注册到新实例 他们调用getPostalCode()。此外,如果重新创建UI,它 触发另一个对repository.getPostCode()的调用,而不是使用 之前的通话结果。
有没有更好的方法让class MyViewModel extends ViewModel {
private final PostalCodeRepository repository;
public MyViewModel(PostalCodeRepository repository) {
this.repository = repository;
}
private LiveData<String> getPostalCode(String address) {
// DON'T DO THIS
return repository.getPostCode(address);
}
}
“重做”其ViewModel
来电?也许我可以制作一个方法,说“更新()”而不是“活跃”,但仍然 - 它以不同的方式做同样的事情。
答案 0 :(得分:3)
在这里,你正在ViewModel的创建者中进行抓取,它将事物锁定到位。通常他们会建议在getter中获取数据,如果数据不存在的话。
所以一个好的选择是首先使用常规模式:
private MutableLiveData<Users> users = null;
ViewModel(ViewModelRepo repo){
this.repo = repo;
}
LiveData<Users> getUsers() {
if (users = null) {
fetchUsers();
}
return users;
}
public void fetchUsers() {
users.postValue(repo.getUsers());
}
然后从您的活动/片段中,只要您觉得有必要“刷新用户”,您只需致电viewModel.fetchUsers();