EasyHttp
EasyHttp copied to clipboard
[疑惑]:USE_CACHE_FIRST缓存的问题
问题描述【必填】
我使用 CacheMode.USE_CACHE_FIRST的时候如果我删除了列表的某项数据然后刷新列表,第一次刷新后使用的还是旧的缓存数据,第二次刷新才会返回新的数据。这个有什么办法解决吗
框架文档是否提及了该问题【必答】
否
是否已经查阅框架文档但还未能解决的【必答】
是
issue 列表中是否有人曾提过类似的问题【必答】
否
是否已经搜索过了 issue 列表但还未能解决的【必答】
是
小伙子,就算没有删除列表项这一说,列表的数据我个人不建议你缓存,因为列表的数据本身就是多变的。
public final class RequestHandler implements IRequestHandler {
@Nullable
@Override
public Object readCache(@NonNull HttpRequest<?> httpRequest, @NonNull Type type, long cacheTime) {
String cacheKey = HttpCacheManager.generateCacheKey(httpRequest);
String cacheValue = HttpCacheManager.readHttpCache(cacheKey);
if (cacheValue == null || cacheValue.isEmpty() || "{}".equals(cacheValue)) {
return null;
}
EasyLog.printLog(httpRequest, "----- read cache key -----");
EasyLog.printJson(httpRequest, cacheKey);
EasyLog.printLog(httpRequest, "----- read cache value -----");
EasyLog.printJson(httpRequest, cacheValue);
EasyLog.printLog(httpRequest, "cacheTime = " + cacheTime);
boolean cacheInvalidate = HttpCacheManager.isCacheInvalidate(cacheKey, cacheTime);
EasyLog.printLog(httpRequest, "cacheInvalidate = " + cacheInvalidate);
if (cacheInvalidate) {
// 表示缓存已经过期了,直接返回 null 给外层,表示缓存不可用
return null;
}
return GsonFactory.getSingletonGson().fromJson(cacheValue, type);
}
@Override
public boolean writeCache(@NonNull HttpRequest<?> httpRequest, @NonNull Response response, @NonNull Object result) {
String cacheKey = HttpCacheManager.generateCacheKey(httpRequest);
String cacheValue = GsonFactory.getSingletonGson().toJson(result);
if (cacheValue == null || cacheValue.isEmpty() || "{}".equals(cacheValue)) {
return false;
}
EasyLog.printLog(httpRequest, "----- write cache key -----");
EasyLog.printJson(httpRequest, cacheKey);
EasyLog.printLog(httpRequest, "----- write cache value -----");
EasyLog.printJson(httpRequest, cacheValue);
boolean writeHttpCacheResult = HttpCacheManager.writeHttpCache(cacheKey, cacheValue);
EasyLog.printLog(httpRequest, "writeHttpCacheResult = " + writeHttpCacheResult);
boolean refreshHttpCacheTimeResult = HttpCacheManager.setHttpCacheTime(cacheKey, System.currentTimeMillis());
EasyLog.printLog(httpRequest, "refreshHttpCacheTimeResult = " + refreshHttpCacheTimeResult);
return writeHttpCacheResult && refreshHttpCacheTimeResult;
}
@Override
public boolean deleteCache(@NonNull HttpRequest<?> httpRequest) {
String cacheKey = HttpCacheManager.generateCacheKey(httpRequest);
EasyLog.printLog(httpRequest, "----- delete cache key -----");
EasyLog.printJson(httpRequest, cacheKey);
boolean deleteHttpCacheResult = HttpCacheManager.deleteHttpCache(cacheKey);
EasyLog.printLog(httpRequest, "deleteHttpCacheResult = " + deleteHttpCacheResult);
return deleteHttpCacheResult;
}
@Override
public void clearCache() {
HttpCacheManager.clearCache();
}
public final class HttpCacheManager {
private static final MMKV HTTP_CACHE_CONTENT = MMKV.mmkvWithID("http_cache_content");;
private static final MMKV HTTP_CACHE_TIME = MMKV.mmkvWithID("http_cache_time");
/**
* 生成缓存的 key
*/
@NonNull
public static String generateCacheKey(@NonNull HttpRequest<?> httpRequest) {
IRequestApi requestApi = httpRequest.getRequestApi();
return "请替换成当前的用户 id" + "\n" + requestApi.getApi() + "\n" + GsonFactory.getSingletonGson().toJson(requestApi);
}
/**
* 读取缓存
*/
public static String readHttpCache(@NonNull String cacheKey) {
String cacheValue = HTTP_CACHE_CONTENT.getString(cacheKey, null);
if (cacheValue == null || cacheValue.isEmpty() || "{}".equals(cacheValue)) {
return null;
}
return cacheValue;
}
/**
* 写入缓存
*/
public static boolean writeHttpCache(String cacheKey, String cacheValue) {
return HTTP_CACHE_CONTENT.putString(cacheKey, cacheValue).commit();
}
/**
* 删除缓存
*/
public static boolean deleteHttpCache(String cacheKey) {
return HTTP_CACHE_CONTENT.remove(cacheKey).commit();
}
/**
* 清理缓存
*/
public static void clearCache() {
HTTP_CACHE_CONTENT.clearMemoryCache();
HTTP_CACHE_CONTENT.clearAll();
HTTP_CACHE_TIME.clearMemoryCache();
HTTP_CACHE_TIME.clearAll();
}
/**
* 获取 Http 写入缓存的时间
*/
public static long getHttpCacheTime(String cacheKey) {
return HTTP_CACHE_TIME.getLong(cacheKey, 0);
}
/**
* 设置 Http 写入缓存的时间
*/
public static boolean setHttpCacheTime(String cacheKey, long cacheTime) {
return HTTP_CACHE_TIME.putLong(cacheKey, cacheTime).commit();
}
/**
* 判断缓存是否过期
*/
public static boolean isCacheInvalidate(String cacheKey, long maxCacheTime) {
if (maxCacheTime == Long.MAX_VALUE) {
// 表示缓存长期有效,永远不会过期
return false;
}
long httpCacheTime = getHttpCacheTime(cacheKey);
if (httpCacheTime == 0) {
// 表示不知道缓存的时间,这里默认当做已经过期了
return true;
}
return httpCacheTime + maxCacheTime < System.currentTimeMillis();
}
}
@1399513637 如果你硬是要实现这个需求,可以下载上面的 aar 包进行替换,修改项目中缓存的实现逻辑,另外这一期我修改了框架对外的 api 的参数类型,这块对于你来讲改动有点大,但是仅限参数类型改变了而已,其他实现的没有太大变化,适配完记得多测试一下,有问题记得跟我反馈。
然后针对你说的删除列表项后对缓存数据刷新的问题,你可以使用 EasyConfig.getInstance().getHandler().deleteCache(HttpRequest<?> httpRequest); 来对原有的缓存内容进行删除。
好的,我明白了。十分感谢