【发布时间】:2017-07-30 17:55:23
【问题描述】:
当我使用ViewModel 测试一个小代码时,我注意到一个逻辑上正确的小问题,我想知道你是如何解决这个问题的。让我们看看这个小班:
public class MyDataViewModel extends ViewModel {
MutableLiveData<List<MyData>> mData = new MutableLiveData<>();
public ContactsViewModel() {}
public void setData(List<MyData> data) {
mData.postValue(data);
}
public LiveData<List<MyData>> getData() {
return mData;
}
}
问题是如果你使用setData()改变LiveData在LiveData观察者注册之前,你的观察者不会在注册观察者后触发。虽然看起来合乎逻辑,但是写异步代码的时候会出问题,在注册observer之前不知道setData()会不会被调用。我想知道当你想注册观察者时如何检查数据是否已经设置。只需检查getData().getValue() != null?
另一个问题是数据同步。我是否需要牢记LiveData 同步(就像所有其他正常数据一样),或者LiveData 在内部处理它?比如setData()和getData().getValue()可以同时被调用吗?
最后一个问题,似乎LiveData观察者会在你设置一个值时触发,即使它是同一个值(例如,如果你在onLoadFinished()中使用setData()Loader,setData()每次重新创建活动时都会调用)。这将导致使用相同数据调用两次观察者。我想知道防止这种情况的最佳方法是什么。检查ViewModel中的数据是否与我们已有的数据相似,不再设置值?
【问题讨论】:
-
LiveData + ViewModel 存在,所以我认为你不需要使用 Loader。
-
@EpicPandaForce 不,它们的存在是为了解决片段s 和活动之间的数据共享问题。 ViewModel 的片段间数据共享非常棒,但我认为它们不会影响 Loader 的使用。
-
MutableLiveData<List<MyData>>而不是MutableLiveData<ArrayList<MyData>>的任何特殊原因? -
允许
MutableLiveData中的数据可变并不是一个很好的做法,因此通常将数组列表包装在Collections.unmodifiableList()中会更好。除非您set/postValue和ArrayList不会阻止它,否则它不应该是可修改的。所以MutableLiveData<List<T>>使这成为可能:D