zoukankan      html  css  js  c++  java
  • 一网打尽OkHttp中的缓存问题

    看到很多小伙伴对OkHttp的缓存问题并不是十分了解,于是打算来说说这个问题。用好OkHttp中提供的缓存,可以帮助我们更好的使用Retrofit、Picasso等配合OkHttp使用的框架。OK,废话不多说,我们来看看OkHttp中的缓存。

    OkHttp中的缓存整体上来说我们要在两个地方配置,一个是构造OkHttpClient时,还有一个是在构造Request时,一共就这两处,那我们分别来看看。

    本文主要包含如下两方面:

    1.在OkHttpClient构造时设置缓存路径

    2.构造Request时配置缓存策略

    OK,那就一步一步来看吧。

    1.在OkHttpClient构造时设置缓存路径

    我们在使用OkHttp的时候,一般都会将client的获取封装起来,因为在大多数情况下,我们需要的OkHttpClient其实都是一样的。在封装的过程中,我们可以设置很多属性,比如链接超时时间、读取超时时间等,其中也包括我们即将要说的cache,我们可以在这里来配置cache路径,配置了cache路径之后,OkHttp请求到的数据就会缓存到该路径下,当手机没有联网的时候,就可以直接从缓存中加载数据。我们来看看代码:

    OkHttpClient client = new OkHttpClient.Builder()
                    .connectTimeout(5, TimeUnit.SECONDS)
                    .cache(new Cache(new File(this.getExternalCacheDir(), "okhttpcache"), 10 * 1024 * 1024))
                    .build();

    我这里是设置了缓存的路径为~/mnt/sdcard/Android/data/应用包名/cache/okhttpcache,第二个参数表示缓存区的大小为10M,当缓存区的数据大小超过10M的时候会自动删除已缓存的数据,当我们配置了缓存路径之后,当我发起一个网络 请求之后,如下:

            Request request = new Request.Builder().url("http://www.tngou.net/api/food/list?id=1").build();
            client.newCall(request).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
    
                }
    
                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    if (response.isSuccessful()) {
                        sb = new StringBuffer();
                        try {
                            JSONObject jo = new JSONObject(response.body().string());
                            JSONArray tngou = jo.optJSONArray("tngou");
                            for (int i = 0; i < tngou.length(); i++) {
                                sb.append(tngou.optJSONObject(i).optString("name")).append("
    ");
                            }
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    tv.setText(sb.toString());
                                }
                            });
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                }
            });

    请求完毕之后,用一个TextView将请求结果显示出来,当请求完毕之后,在我们上面所说的那个目录下,可以看到如下三个文件:

    这里有三个文件,其中以.0结尾的文件缓存了http的响应头信息,以.1结尾的文件则缓存了我们下载的json数据,journal则是一个日志文件,我们把这几个文件打开来看看:

    .0


    .1


    journal


    OK,配置了cache之后,当我们请求过一次数据之后,然后关闭掉网络,这个时候再去请求网络数据,这个时候OkHttp会自动从本地缓存中重新加载数据。

    2.构造Request时配置缓存策略

    上面的配置应该已经可以满足许多小伙伴的需求了,可是很多时候我们还有许多其他的需求,那么这些需求我们可以在构造Request的时候通过CacheControl来进行进一步的配置。

    在构造Request的时候,我们可以配置CacheControl,配置有两种方式,一种是构造CacheControl,还有一种是直接使用CacheControl中的常量,我们来分别看一下:

    2.1构造CacheControl

            CacheControl cc = new CacheControl.Builder()
                    //不使用缓存,但是会保存缓存数据
                    //.noCache()
                    //不使用缓存,同时也不保存缓存数据
                   // .noStore()
                    //只使用缓存,(如果我们要加载的数据本身就是本地数据时,可以使用这个,不过目前尚未发现使用场景)
                    //.onlyIfCached()
                    //手机可以接收响应时间小于当前时间加上10s的响应
    //                .minFresh(10,TimeUnit.SECONDS)
                    //手机可以接收有效期不大于10s的响应
    //                .maxAge(10,TimeUnit.SECONDS)
                    //手机可以接收超出5s的响应
                    .maxStale(5,TimeUnit.SECONDS)
                    .build();
            Request request = new Request.Builder()
                    .cacheControl(cc)
                    .url("http://192.168.152.2:8080/cache").build();

    这个用起来还是比较简单的,没什么好说的,重要代码看注释。

    2.2使用CacheControl中的常量

    如果直接使用CacheControl中的常量,则不用调用上面那么多的方法,使用方式如下:

            Request request = new Request.Builder()
                    //强制使用网络
    //                .cacheControl(CacheControl.FORCE_NETWORK)
                    //强制使用缓存
                    .cacheControl(CacheControl.FORCE_CACHE)
                    .url("http://192.168.152.2:8080/cache").build();

    OK,这个就是我们OkHttp中缓存的一个基本使用,有问题欢迎留言讨论。


    以上。



  • 相关阅读:
    BZOJ 2244 [SDOI2011]拦截导弹 (三维偏序CDQ+线段树)
    BZOJ 2141 排队 (三维偏序CDQ+树状数组)
    BZOJ 3295 [CQOI2011]动态逆序对 (三维偏序CDQ+树状数组)
    BZOJ 3262 陌上花开 (三维偏序CDQ+树状数组)
    BZOJ 4012 [HNOI2015]开店 (树分治+二分)
    CF1090H Linearization
    BZOJ 4141 [Thu Summer Camp 2013]魔塔
    luogu P4654 [CEOI2017]Mousetrap
    luogu P4548 [CTSC2006]歌唱王国
    [总结] min-25筛
  • 原文地址:https://www.cnblogs.com/qitian1/p/6461652.html
Copyright © 2011-2022 走看看