我有两个使用公共存储库的片段。使用RxJava和switchIfEmpty管理存储库数据缓存()
我正在尝试为此存储库实现缓存管理系统。
的理念是: 其中一个片段被加载,它调用getData()
方法,这个方法使使用getDataFromNetwork()
网络调用远程JSON API时,得到的结果,并把它放在高速缓存为List<Aqicn>
(中data
变量在我的代码中)。
下一个片段被加载。如果它发生在60秒之前,那么没有网络呼叫,数据直接来自我的数据列表中的缓存,使用getDataFromMemory()
。
RxJava Observable.switchIfEmpty()
用于了解Observable(my ArrayList)是否为空并调用正确的方法。
我不知道如何登场,所以我只是把一个按钮放在我的主布局上。当我启动我的应用程序时,第一个片段会自动加载,第一次调用getData()
。当我按下这个按钮时,它加载第二个片段,第二次调用getData()
。
如果我在60秒前按下此按钮,我不应该有一个网络调用到JSON api,但是...我有一个,我总是得到第二个网络调用,我的缓存数据不使用。我的代码有什么问题?
public class CommonRepository implements Repository {
private static final String TAG = CommonRepository.class.getSimpleName();
private long timestamp;
private static final long STALE_MS = 60 * 1000; // Data is stale after 60 seconds
private PollutionApiService pollutionApiService;
private ArrayList<Aqicn> data;
public CommonRepository(PollutionApiService pollutionApiService) {
this.pollutionApiService = pollutionApiService;
this.timestamp = System.currentTimeMillis();
data = new ArrayList<>();
}
@Override
public Observable<Aqicn> getDataFromNetwork(String city, String authToken) {
Observable<Aqicn> aqicn = pollutionApiService.getPollutionObservable(city, authToken)
.doOnNext(new Action1<Aqicn>() {
@Override
public void call(Aqicn aqicn) {
data.add(aqicn);
}
});
return aqicn;
}
private boolean isUpToDate() {
return System.currentTimeMillis() - timestamp < STALE_MS;
}
@Override
public Observable<Aqicn> getDataFromMemory() {
if (isUpToDate()) {
return Observable.from(data);
} else {
timestamp = System.currentTimeMillis();
data.clear();
return Observable.empty();
}
}
@Override
public Observable<Aqicn> getData(String city, String authToken) {
return getDataFromMemory().switchIfEmpty(getDataFromNetwork(city, authToken));
}
}
=======编辑:我简化了我的代码,以最小===========
public class CommonRepository implements Repository {
private PollutionApiService pollutionApiService;
private static Observable<Aqicn> cachedData = null;
public CommonRepository(PollutionApiService pollutionApiService) {
this.pollutionApiService = pollutionApiService;
}
@Override
public Observable<Aqicn> getDataFromNetwork(String city, String authToken) {
Observable<Aqicn> aqicn = pollutionApiService.getPollutionObservable(city, authToken);
cachedData = aqicn;
return aqicn;
}
@Override
public Observable<Aqicn> getData(String city, String authToken) {
if(cachedData == null) {
return getDataFromNetwork(city, authToken);
}
return cachedData;
}
}
而就意识到,不管是什么我这样做,当我做return cachedData
网络通话后...
=====编辑发现的问题,但没有解决发现==========
在我的构造函数中,我启动了我的污染服务。 这种使用匕首的JSON请求,并返回一个可观察:
public interface PollutionApiService {
@GET("feed/{city}/")
Observable<Aqicn> getPollutionObservable(@Path("city") String city, @Query("token") String token);
}
我不知道这一切是如何工作的细节,但我interprate这样。 Dagger创建一个可观察的PollutionApiService提供者。当我做return cachedData
这Observable订阅,所以网络通话已完成...但不知道如何解决它。事实是,我每次做return cachedData
都有网络电话。
你希望缓存给定PARAMS所有的请求?如果你打电话给城市第一个getData:'Hamburg'和auth:X,然后'Berlin','X',这两个请求是否应该被缓存60秒?在您当前的实现中,您只需将每个请求的元素添加到缓存中。 –
这两个调用中的参数都相同。 – Laurent