所以我试图使用Guava缓存来缓存HTTP响应(使用OkHtttp +改进,rxjava用于多线程)。当前看起来像:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://blablabla.com")
.client(client)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
apiClient = retrofit.create(Api.class);
CacheLoader<Integer, HttpResponse> cacheLoader = new CacheLoader<Integer, HttpResponse>() {
@Override
public Response load( Integer key ) throws InterruptedException, ExecutionException {
return apiClient.getHttpResponse(key)
.subscribeOn(Schedulers.io())
.blockingFirst();
}
};
responseCache = CacheBuilder.newBuilder()
.concurrencyLevel(8)
.maximumSize( 10 )
.build(cacheLoader);
apiClient返回Observable,并在CacheLoader的load方法中进行预订。我还设置了concurrencyLevel(8)
,但似乎不允许同时“加载”和“读取”。
我认为blockingFirst()
调用可能会阻塞线程,因此我无法从缓存发出并发请求,即,只要缓存加载新的http响应,就无法读取缓存。
我不知道如何使其异步,不胜感激:)
答案 0 :(得分:0)
使用Guava,您仍然可以进行异步非阻塞调用并缓存HTTP响应,但是在收到HTTP响应后,您将必须手动调用cache.put()。因此,您可以像下面定义您的LoadingCache。
private LoadingCache<String, ServerResponse> cache =
CacheBuilder.newBuilder()
.maximumSize(50)
.expireAfterWrite(24, TimeUnit.HOURS)
.build(
new CacheLoader<String, ServerResponse>() {
public ServerResponse load(String id) {
return null; // or empty ServerResponse
}
});
在您的调用方法中:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://blablabla.com")
.client(client)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
apiClient = retrofit.create(Api.class);
try {
ServerResponse cachedResponse = cache.get(someUniqueKey);
if (cachedResponse != null) {
// return cachedResponse here
return;
}
doNormalHttpRequest()
} catch (ExecutionException | CacheLoader.InvalidCacheLoadException e) {
doNormalHttpRequest();
}
void doNormalHttpRequest() {
apiClient.request(body).enqueue(
new retrofit2.Callback<ServerResponse>() {
@Override
public void onResponse(Call<ServerResponse> call,
Response<ServerResponse> response) {
if (response.isSuccessful()) {
cache.put(someUniqueKey, response.body();
}
}
@Override
public void onFailure(Call<ServerResponse> call, Throwable {}
});
}
此外,由于改型仅使用OkHttp的缓存实现来缓存GET请求,因此它还可以缓存POST请求。