【发布时间】:2017-08-14 10:24:24
【问题描述】:
所以,我刚刚开始尝试使用 LiveData - 我正忙于一个新项目,我正在使用 ViewModel 和 LiveData - 以及我用来获取数据的一些 RESTFul 服务,它们不带参数并返回一些数据。
带有LiveData 的 MVVM 范例的典型设置如下所示:
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 没有被调用) - 然后回到@987654328 @ - 我们当然不会再次获取users,因为我们应该仍然拥有该数据。
但是,如果我们确实想再次获取它们怎么办?
据我所见,正确执行此操作的唯一方法似乎是在 getUsers() LiveData 对象上调用“setValue”
类似这样的:
public class MyActivity extends AppCompatActivity {
public void onResume() {
viewModel.setActive(true);
}
}
ViewModel 看起来像这样:
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);
}
我决定这样做的一个原因是因为 Google 不希望我们这样做:
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);
}
}
出于这个原因:
如果这是实现,则 UI 需要从 以前的 LiveData 并每次重新注册到新实例 他们调用 getPostalCode()。此外,如果重新创建 UI,它 触发对 repository.getPostCode() 的另一个调用,而不是使用 上一次调用的结果。
有没有更好的方法让ViewModel“重做”它的repo.getUsers() 调用?也许我可以只做一个方法,说“更新()”而不是“活动”,但仍然 - 它以不同的方式做同样的事情。
【问题讨论】:
标签: android mvvm android-architecture-components android-viewmodel