Rxjava - 如果尚未调用,则仅调用网络

时间:2018-01-20 19:45:48

标签: java android rx-java retrofit2

我正在使用retrofit和rxjava创建一个存储库,如果之前没有检索到任何数据,它将调用网络,如果存在,则从内存返回缓存。

但是,失败的地方是如果同时调用存储库,它将多次调用网络。这是我目前的解决方案,其中存储库是一个单独的存储器,并存储网络调用是否已在进行中,如果是这样,则只返回内存可观察对象。

IDatabaseInteractor databaseInteractor;
INetworkInteractor networkInteractor;
Data data;

boolean networkCallInProgress = false;

@Override
public Observable<Data> getData() {
    Observable<Data> memoryObservable = data.getObservable();
    Observable<Data> networkObservable;

    //Sure this could be done in a better way...
    if (!networkCallInProgress) {
        getBoostersInPnetworkCallInProgressrogress = true;
        networkObservable = networkInteractor.getBoosters().toObservable()
                .doFinally(() -> networkCallInProgress = false);
    } else {
        networkObservable = Observable.empty();
    }

    return Observable.merge(memoryObservable, networkObservable)
            .firstElement()
            .toObservable()
            .onErrorResumeNext((throwable) -> memoryObservable)
            .flatMap(boosterData -> memoryObservable);
}

这样可行,但使用rxjava是否有一个更优雅的解决方案来了解网络可观察是否已被调用?

2 个答案:

答案 0 :(得分:0)

首先,您可以通过Dagger使用Singleton实现,它实际上只保留了与您的存储库类的一次性创建对象的链接。

根据多次执行,您可以使用一个流(例如rx订阅甚至是android的LiveData)将数据从您的存储库(例如ViewModel内部)恢复到您的视图,其他流来获取您的数据。

  1. 当您创建存储库时,您将开始重复下载 规则从服务器获取数据并填充LiveData流。
  2. 在 你的观点只是听LiveData流。
  3. 在这种情况下,您只会在没有任何检查的情况下调用它一次,并从任何应附加到您的仓库的视图中获取数据。

答案 1 :(得分:0)

我通常会采用下一种方式:

1.-云和磁盘数据存储应该执行相同的操作,然后创建一个接口DataStore

interface DataStore {
  private void Observable<SOmeData> getTheData();
}

2.-创建缓存系统。

3.-创建CloudDataStoreDiskDataStore,两者都必须实现DataStore接口。 DiskDataStore应包含缓存,并使用Cache

中定义的操作包装其操作

4.-创建DataStoreFactory并注入两者(云和磁盘数据存储)。在这里,您可以创建以下方法:

private DataStore createDataStoreForUserListForExample(boolean force) {
    if (force) //you want a network call because maybe is a refresh from a pull to refresh
        return cloudDataStore
    else {
        if (cache.usersListIsCached()) return diskDataStore
        else return cloudDataStore
    }
}

5.-现在,创建您的存储库并在其中注入DataStoreFactory。在这里,您应该具有以下功能:

public void Observable<SomeData> getTheList(boolean force) {
  DataStore ds = factory.createDataStoreForUserListForExample(force);
  return ds.getTheData();
}