androidmvvmandroid-livedatamediatorlivedata

MediatorLiveData calls old data before addSource's observed LiveData returns


Below, is the method I have in my repository:

public LiveData<Trail> getRandomTrail() {
    final LiveData<Trail> currentRandomTrail = trailDao.getRandomTrail(getMaxRefreshTime());

    randomTrail.addSource(currentRandomTrail, trail -> {
        if (trail == null) {
            loadTrailsFromNetwork();
        } else {
            randomTrail.removeSource(currentRandomTrail);
            randomTrail.postValue(trail);
        }
    });
    return randomTrail;
}

This problem is that the UI briefly displays outdated data, but I am expecting the MediatorLiveData object, randomTrail, to wait until currentRandomTrail has returned it's value. Outdated data first appears, then the MediatorLiveData object updates. Any idea why my MediatorLiveData object is not working how expected?


Solution

  • Any idea why my MediatorLiveData object is not working how expected?

    This happens because first getRandomTrail() will be executed, returning a MediatorLiveData object with an outdated value. Only after execution of this method has finished, the next method can start running. So the following snippet will never be finished in time to return randomTrail with a current value from the surrounding method getRandomTrail():

    trail -> {
        if (trail == null) {
            loadTrailsFromNetwork();
        } else {
            randomTrail.removeSource(currentRandomTrail);
            randomTrail.postValue(trail);
        }
    }
    

    One approach to deal with this situation:

    When you start loading the current data in getRandomTrail(), let randomTrail have some value which will be recognized as invalid by the ViewModel/ the UI. That way, you can prevent showing outdated values - maybe show some type of progressbar instead.