3

我正在寻找处理以下用例 wrt LiveData 处理的建议:ViewModel 为 LiveData 调用存储库(例如产品目录)。存储库首先从 LocalDataSource(Room) 检查,但如果数据不可用,则调用 RemoteDataSource(REST API)。

问题:

1) 根据 yigit here的以下评论,存储库在作为观察者订阅之前无法在 Room 中获取 LiveData 可用性状态。因此,即使数据可用,我也会得到 null 作为响应。 “LiveData 是观察数据并将其分发给观察者。在添加活动观察者之前,它不会计算值。”

由于存储库对客户端隐藏数据源,因此存储库有责任签入 Room,然后从远程源中提取。它如何检查 Room 中的数据可用性?

2) 由于 RemoteDataSource 返回的数据不是 LiveData 类型,应该怎么做才能使存储库最终返回 LiveData 给 ViewModel ?

Repository 是否应该首先将数据(来自 RemoteDataSource)插入 Room,然后查询 Room 以返回 LiveData ?它看起来相当昂贵的操作,因为在此过程中会查询 Room 两次。请指教 。谢谢 !

4

2 回答 2

2

首先,感谢@adityakamble49回答我的问题,感谢他!您可以通过将 LiveData 作为返回值并使用NetworkBoundResource来使用 Repository 来维护抽象,您可以决定是否需要从 Network 获取或可以使用缓存数据(DB / DataHolder)。NetworkBoundResource 是一种在抽象类中实现通用功能(使用泛型)并在扩展类中提供显式行为的干净方法。

在NetworkBoundResource类与android-priority-jobqueue上分享我的观点,这样它可以帮助我们决定在各种场景中使用哪一个。

NetworkBoundResource - 当应用程序需要从本地数据库或网络获取数据但在获取失败时向用户显示错误时使用(例如,没有网络)。在屏幕上拉到刷新是一个很好的用例,用户希望看到更新的数据,或者如果提取失败,则会看到错误消息/对话框。

android-priority-jobqueue - 有很多场景需要保留一个动作直到它成功完成(而不是显示错误并忘记)。JobQueue 在这种情况下有助于在后台队列中维护待处理的作业(用于关联的触发器),然后在网络可用时处理它们。例如,用户在离线模式下创建的注释被添加到 JobQueue 中,稍后在设备上线时同步。NetworkBoundResource 无法解决这种情况。

不应使用 JobQueue 处理 NetworkBoundResource 候选操作(反之亦然),因为它可能会用太多操作淹没 JobQueue 并且其中许多可能是重复的,例如同一屏幕上的多个 Pull To Refresh 操作导致多个作业,这是错误的. 欢迎他人观点!!!

于 2018-04-06T06:14:00.653 回答
1

我建议先在数据库中插入数据,然后使用Room将其作为LiveData进行观察。您需要使用 Room 提供的 LiveData 观察数据库,并从 Repository 更新数据库中的 REST API 响应。

需要使用 ViewModel来保存从 Activity / Fragment 中的数据库观察到的所有 LiveData 对象。

检查NetworkBoundResource他们在 Android 架构组件指南中提供的 Room 使用类中数据可用性。

但是如果你觉得这个操作很昂贵并且不想将每个数据都存储在数据库中,那么可以使用 MutableLiveData 在一些 DataHolder 类中创建简单的 LiveData 变量。

public class DataHolder {

// Create a LiveData using MutableLiveData
private LiveData<String> data;

    public LiveData<String> getData() {
        if (data == null) {
            data = new MutableLiveData<String>();
        }
        return data;
    }

    public void updateData(String value) {
        data.setValue(value);
    }
}

在这种情况下, DataHolder 不是 ViewModel,因为不建议直接从下层组件更新上层组件。有关详细信息,请参阅此图Android 架构组件

在存储库的getData()方法中调用getData()来自 DataHolder。基本上包装该方法以对上层进行抽象。

使用updateData()包装器setValue(T)从RestAPI 响应更新 LiveData 变量。postValue(T)

于 2018-02-26T05:01:39.097 回答