【问题标题】:MediatorLiveData calls old data before addSource's observed LiveData returnsMediatorLiveData 在 addSource 观察到的 LiveData 返回之前调用旧数据
【发布时间】:2020-04-18 20:24:55
【问题描述】:

下面是我的存储库中的方法:

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;
}

这个问题是 UI 短暂显示过时的数据,但我希望 MediatorLiveData 对象 randomTrail 等到 currentRandomTrail 返回它的值。过时的数据首先出现,然后 MediatorLiveData 对象更新。知道为什么我的 MediatorLiveData 对象没有按预期工作吗?

【问题讨论】:

    标签: android mvvm android-livedata mediatorlivedata


    【解决方案1】:

    知道为什么我的 MediatorLiveData 对象没有按预期工作吗?

    这是因为第一个 getRandomTrail() 将被执行,返回一个带有过期值的 MediatorLiveData 对象。只有在该方法执行完成后,下一个方法才能开始运行。所以下面的 sn-p 永远不会及时完成返回 randomTrail 与来自周围方法 getRandomTrail() 的当前值:

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

    处理这种情况的一种方法:

    当您开始在getRandomTrail() 中加载当前数据时,让randomTrail 具有一些值,该值将被ViewModel/ UI 识别为无效。 这样,您可以防止显示过时的值 - 可能会显示某种类型的进度条。

    【讨论】:

    • 我只是在方法的开头添加了 randomTrail.setValue(null) 并且它起作用了!我还将以某种方式实现加载栏。谢谢您的帮助。但是,这个问题正常吗?这似乎是一种解决方法。我想知道是否有更好的方法来设计我的代码以防止调用这个过时的值。
    • @Amboseli - afaik 这是正常行为。我见过的另一种更复杂的方法(在某些代码实验室中)是有一个通用类 Result 和子类 Success (这个有一个类型为 T 的字段数据)、 Loading 和 Error (这个具有例如 Throwable 类型的字段)。然后可以公开一个 LiveData>
    猜你喜欢
    • 2019-06-02
    • 1970-01-01
    • 2019-02-04
    • 2021-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-22
    • 1970-01-01
    相关资源
    最近更新 更多