XUtils3.0 解决不缓存问题

XUtils3.0 解决不缓存问题

xutils3.0是一次彻底的重构, api发生了很大变化, 但是仍然保持着xUtils一贯的简介风格, 并且新的api更加简单, 更具扩展性。参考sample写的案例发现不走缓存(onCache)。原因可能为以下两种:

1. 未设置缓存
2. 接口返回头expires设置过期时间为过去时间(即不缓存)


1. 未设置缓存

通过调用 setCacheMaxAge()设置缓存时间,单位毫秒

BaiduParams params = new BaiduParams();
        params.wd = "xUtils";
        // 默认缓存存活时间, 单位:毫秒.(如果服务没有返回有效的max-age或Expires)
        params.setCacheMaxAge(1000 * 60);
        Callback.Cancelable cancelable
                // 使用CacheCallback, xUtils将为该请求缓存数据.
                = x.http().get(params, new Callback.CacheCallback() {

            private boolean hasError = false;
            private String result = null;

            @Override
            public boolean onCache(String result) {
                // 得到缓存数据, 缓存过期后不会进入这个方法.
                // 如果服务端没有返回过期时间, 参考params.setCacheMaxAge(maxAge)方法.
                //
                // * 客户端会根据服务端返回的 header 中 max-age 或 expires 来确定本地缓存是否给 onCache 方法.
                //   如果服务端没有返回 max-age 或 expires, 那么缓存将一直保存, 除非这里自己定义了返回false的
                //   逻辑, 那么xUtils将请求新数据, 来覆盖它.
                //
                // * 如果信任该缓存返回 true, 将不再请求网络;
                //   返回 false 继续请求网络, 但会在请求头中加上ETag, Last-Modified等信息,
                //   如果服务端返回304, 则表示数据没有更新, 不继续加载数据.
                //
                this.result = result;
                return false; // true: 信任缓存数据, 不在发起网络请求; false不信任缓存数据.
            }

            @Override
            public void onSuccess(String result) {
                // 注意: 如果服务返回304或 onCache 选择了信任缓存, 这里将不会被调用,
                // 但是 onFinished 总会被调用.
                this.result = result;
            }

            @Override
            public void onError(Throwable ex, boolean isOnCallback) {
                hasError = true;
                Toast.makeText(x.app(), ex.getMessage(), Toast.LENGTH_LONG).show();
                if (ex instanceof HttpException) { // 网络错误
                    HttpException httpEx = (HttpException) ex;
                    int responseCode = httpEx.getCode();
                    String responseMsg = httpEx.getMessage();
                    String errorResult = httpEx.getResult();
                    // ...
                } else { // 其他错误
                    // ...
                }
            }

            @Override
            public void onCancelled(CancelledException cex) {
                Toast.makeText(x.app(), "cancelled", Toast.LENGTH_LONG).show();
            }

            @Override
            public void onFinished() {
                if (!hasError && result != null) {
                    // 成功获取数据
                    Toast.makeText(x.app(), result, Toast.LENGTH_LONG).show();
                }
            }
        });

2. 接口返回头expires设置过期时间为过去时间(即不缓存)

在使用注解模板时,可以在responseParser里面手动缓存

public class JsonResponseParser implements ResponseParser {
    private UriRequest request;

    @Override
    public void checkResponse(UriRequest request) throws Throwable {
    //请求网络时候走这里
        this.request = request;
    }

    @Override
    public Object parse(Type resultType, Class resultClass, String result) throws Throwable {
    //解析,缓存先走这里,如果缓存没有找到或者未设置缓存,那么再走checkResponse
    //如果服务器接口返回缓存过期时间为过去时间(即不缓存)那么手动设置过期时间为
    //System.currentTimeMillis() + request.getParams().getCacheMaxAge()

        if (request != null && !TextUtils.isEmpty(result) && request.getExpiration() < System.currentTimeMillis()) {
            DiskCacheEntity entity = new DiskCacheEntity();
            entity.setKey(request.getCacheKey());
            entity.setLastAccess(System.currentTimeMillis());
            entity.setEtag(request.getETag());
//            entity.setExpires(request.getExpiration());
            entity.setExpires(System.currentTimeMillis() + request.getParams().getCacheMaxAge());
            entity.setLastModify(new Date(request.getLastModified()));
            entity.setTextContent(result);
            LruDiskCache.getDiskCache(request.getParams().getCacheDirName()).put(entity);
        }
        if (resultClass == List.class) {
            // fastJson 解析:
            return JSON.parseArray(result, (Class) ParameterizedTypeUtil.getParameterizedType(resultType, List.class, 0));
        } else {
            // fastjson 解析:
            return JSON.parseObject(result, resultClass);
        }
    }
}

感谢wyouflf的帮助

你可能感兴趣的:(Android开发笔记)