我有兩個使用公共存儲庫的片段。使用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