When I was testing a small code using ViewModel, I noticed a small logically correct problem and I wonder how you counter this problem. Let's see this small class:
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;
}
}
Problem is that if you use setData() to change LiveData before LiveData observer is registered, your observer will not trigger after registering observer. Even though it seems logical, but it can cause problems when you write asynchronous codes, and you don't know if setData() will be called before registering observer or not. I wonder how you check if data is already set when you want to register observer. Just check if getData().getValue() != null?
Another question is data synchronization. Do I need to keep LiveData synchronization in mind (like all other normal data), or LiveData internally handles it? For example, can setData() and getData().getValue() get called at same time?
Last problem, it seems LiveData observers will trigger anytime you set a value, even if it is the same one(For example, if you use setData() in onLoadFinished() of a Loader, setData() will be called every time activity recreates). This will cause observer called twice with same data. I wonder what is best way to prevent this. Check if data in ViewModel is similar to what we have and don't set value again?
MutableLiveData<List<MyData>>rather thanMutableLiveData<ArrayList<MyData>>?MutableLiveDatato be mutable, so generally wrapping the array list inCollections.unmodifiableList()is better. It shouldn't be modifiable unless youset/postValue, andArrayListdoes not prevent that. SoMutableLiveData<List<T>>makes that possible :D