RXJava中如何使用ETag缓存

还是启动图的问题,上一个版本使用队列缓存启动图,但是ios端总是出问题,不得已,在这一版中,后台又重现制定了启动图显示加载规则,于是就有了这篇博文。

ETag字符串通常是用来标记服务器缓存的,当客户端第一次请求时,服务器会根据当前的数据生成一个ETag字符串,在response中返回。客户端保存这个ETag字符串,当客户端再次发送相同的url请求时,在header中通过If-None-Match字段,将该字符串发送到服务器,服务器根据比较前后ETag的值,返回304来告诉客户端是否需要使用缓存。

在retrofit的网络配置中,通常情况下我们是这样定义接口的:

@GET("/splash_image")
void loadSplashImg(@Header("a") String a,Callback<JumpItemBean> response);

在rxjava+retrofit中,我们通常只是作了一下小小的改变:

@GET("/splash_image")
Observable<JumpItemBean> loadSplashImg(@Header("a") String a);

但是这样的话,我们无法拿到请求头header中返回来的ETag字符串。这时我们就需要变换一下返回值。

@GET("/splash_image")
Observable<Response> loadSplashImg(@Header("a") String a);
//if_none_match 就是保存的ETag字符串的值
   HttpUtils.getInstance().getV4ApiServer().
                loadSplashImage(HttpUtils.getInstance().getHeaderStr("GET"), if_none_match).
                subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).
                map(new Func1<Response, List<JumpItemBean>>() {
                    @Override
                    public List<JumpItemBean> call(Response response) {

                        List<Header> headers = response.getHeaders();
                        String etag = null;
                        //遍历header头中的所有的key,如果有ETag,就获取对应的值
                        for (Header h : headers) {
                            if (h.getName().equalsIgnoreCase("ETag")) {
                                etag = h.getValue();
                            }
                        }
                        List<JumpItemBean> list = null;
                        try {
                            //这里开始获取response实体中的内容
                            InputStream stream = response.getBody().in();
                            byte[] buffer = new byte[2048];
                            int readBytes = 0;
                            StringBuilder stringBuilder = new StringBuilder();

                            while ((readBytes = stream.read(buffer)) != -1) {
                                stringBuilder.append(new String(buffer, 0, readBytes));
                            }
                            Gson gson = new Gson();
                            //当拿到response中的body字符串时,通过gson,将其转为一个集合
                            list = gson.fromJson(stringBuilder.toString(), new TypeToken<List<JumpItemBean>>() {
                            }.getType());
                            if (list != null) {
                                for (JumpItemBean j : list) {
                                    j.setETAG(etag);
                                }
                            }
                            handleSplashList(list);
                            return list;
                        } catch (IOException e) {
                            e.printStackTrace();
                        }

                        return null;
                    }
                }).subscribe(new Observer<List<JumpItemBean>>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {
                if (RxThrowable.getHttpCode(e) == 304) {
                    //这里是自定义的获取HttpCode的方法
                }
            }

            @Override
            public void onNext(List<JumpItemBean> jumpItemBeen) {
                  //这里对启动图集合进行处理
            }
        });
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,373评论 19 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 175,282评论 25 709
  • http协议有http0.9,http1.0,http1.1和http2三个版本,但是现在浏览器使用的是htt...
    一现_阅读 5,877评论 0 3
  • 墙上的挂钟 嘀嗒嘀嗒 窗外的树叶 沙沙沙沙 楼下的孩童 咿咿呀呀 而我却在这里低头 盯着手机装傻 早就把过去贴上蜂...
    慕容锦瑟阅读 4,404评论 0 7
  • 亲爱的妈妈: 您好!三八妇女节快乐! 有一次,我偶然地发现了您在QQ空间里写了许多日志!我点了日志的...
    缓行的蜗牛阅读 3,093评论 1 4