我正在使用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是否有一个更优雅的解决方案来了解网络可观察是否已被调用?
答案 0 :(得分:0)
首先,您可以通过Dagger使用Singleton实现,它实际上只保留了与您的存储库类的一次性创建对象的链接。
根据多次执行,您可以使用一个流(例如rx订阅甚至是android的LiveData)将数据从您的存储库(例如ViewModel内部)恢复到您的视图,其他流来获取您的数据。
在这种情况下,您只会在没有任何检查的情况下调用它一次,并从任何应附加到您的仓库的视图中获取数据。
答案 1 :(得分:0)
我通常会采用下一种方式:
1.-云和磁盘数据存储应该执行相同的操作,然后创建一个接口DataStore
interface DataStore {
private void Observable<SOmeData> getTheData();
}
2.-创建缓存系统。
3.-创建CloudDataStore
和DiskDataStore
,两者都必须实现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();
}