okhttp-缓存机制

okhttp提供缓存机制,用于缓存响应head和body,但默认是不开启缓存机制。

启用缓存:

new OkHttpClient().newBuilder().cache(new Cache(new File(“D:/”), 10240)).build();

缓存执行基本流程:

1.执行拦截器链CacheInterceptor,首先会从缓存中读取响应结果
2.okhttp提供Cache类作为缓存的基本操作类,实际缓存操作是通过该类执行

缓存实现基本原理:

存储:
1.okhttp缓存存储是基于文件存储,从启用缓存机制传入的两个参数也可以看出:directory->缓存文件目录,maxSize->缓存支持存储的最大字节数
清理:
1.缓存清理是基于LRU机制,清理最老且使用最少的数据
2.内部维护一个清理线程,当size大于或等于maxSize时就会执行清理操作

关于缓存文件,可以参考一段源码注释:

  • This cache uses a journal file named “journal”. A typical journal file
    looks like this:
    libcore.io.DiskLruCache
    1
    100
    2
    CLEAN 3400330d1dfc7f3f7f4b8d4d803dfcf6 832 21054
    DIRTY 335c4c6028171cfddfbaae1a9c313c52
    CLEAN 335c4c6028171cfddfbaae1a9c313c52 3934 2342
    REMOVE 335c4c6028171cfddfbaae1a9c313c52
    DIRTY 1ab96a171faeeee38496d8b330771a7a
    CLEAN 1ab96a171faeeee38496d8b330771a7a 1600 234
    READ 335c4c6028171cfddfbaae1a9c313c52
    READ 3400330d1dfc7f3f7f4b8d4d803dfcf6
    The first five lines of the journal form its header. They are the
    constant string “libcore.io.DiskLruCache”, the disk cache’s version,
    the application’s version, the value count, and a blank line.
    Each of the subsequent lines in the file is a record of the state of a
    cache entry. Each line contains space-separated values: a state, a key,
    and optional state-specific values.
    o DIRTY lines track that an entry is actively being created or updated.
    Every successful DIRTY action should be followed by a CLEAN or REMOVE
    action. DIRTY lines without a matching CLEAN or REMOVE indicate that
    temporary files may need to be deleted.
    o CLEAN lines track a cache entry that has been successfully published
    and may be read. A publish line is followed by the lengths of each of
    its values.
    o READ lines track accesses for LRU.
    o REMOVE lines track entries that have been deleted.
    The journal file is appended to as cache operations occur. The journal may
    occasionally be compacted by dropping redundant lines. A temporary file named
    “journal.tmp” will be used during compaction; that file should be deleted if
    it exists when the cache is opened.

解释:
1.前五行内容描述的是缓存版本信息相关
2.后面每个子行描述的是缓存数据的状态信息及key对应的信息
3.DIRTY lines->跟踪被修改的数据
CLEAN lines->每次的DIRTY操作后面都需要跟一个CLEAN/REMOVE操作,表示执行已完成
READ lines->跟踪每次读取操作
REMOVE lines->跟踪每次删除操作

通过一个简单例子来测试下okhttp缓存机制

完整源码:https://github.com/ingorewho/do-test/tree/master/okhttp-test

配置代码:

/**
 * @Author: ignore1992
 * @Description: 配置okhttp
 * @Date: Created In 17:45 2019/1/30
 */
public class OkhttpConfig {
    private static volatile OkHttpClient client = null;

    public static OkHttpClient client(){
        if (client == null){
            synchronized (OkhttpConfig.class){
                if (client == null){
                    client = new OkhttpConfig().init();
                }
            }
        }
        return client;
    }

    public OkHttpClient init(){
        OkHttpClient.Builder builder = new OkHttpClient().newBuilder();
        builder.connectTimeout(5, TimeUnit.SECONDS)
                .readTimeout(10, TimeUnit.SECONDS)
                .writeTimeout(10, TimeUnit.SECONDS)
                .addInterceptor(new TestInterceptor())
                .addInterceptor(new OkInterceptor())
                .addNetworkInterceptor(new OkNetInterceptor())
                .retryOnConnectionFailure(true)
                .cache(new Cache(new File("D:/"), 10240))
                .sslSocketFactory(getTrustedSSLSocketFactory())
                .hostnameVerifier(DO_NOT_VERIFY);
        return builder.build();
    }

    TrustManager[] trustAllCerts = new TrustManager[]{
            new X509TrustManager() {
                @Override
                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    X509Certificate[] x509Certificates = new X509Certificate[0];
                    return x509Certificates;
                }
                @Override
                public void checkClientTrusted(
                        java.security.cert.X509Certificate[] certs, String authType) {
                }
                @Override
                public void checkServerTrusted(
                        java.security.cert.X509Certificate[] certs, String authType) {
                }
            }
    };

    HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    };

    private SSLSocketFactory getTrustedSSLSocketFactory() {
        try {
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, trustAllCerts, new java.security.SecureRandom());
            return sc.getSocketFactory();
        } catch (KeyManagementException | NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }
    }
}

测试代码:

/**
 * @Author: ignore1992
 * @Description:
 * @Date: Created In 14:48 2019/1/31
 */
public class Main {
    public static void main(String[] args) {
        //1.重复执行get同步请求,为了方便查看缓存命中信息
        System.out.println(ProcessOkhttp.get("https://api.apiopen.top/searchAuthors?name=%E6%9D%8E%E7%99%BD", null));
        System.out.println(ProcessOkhttp.get("https://api.apiopen.top/searchAuthors?name=%E6%9D%8E%E7%99%BD", null));
    }
}

查看缓存目录下:D:/文件夹下出现三个文件:
journal文件(记录缓存操作记录)
99e43630a8fed826b8b19a06e1b8d09e.0文件(记录header信息)
99e43630a8fed826b8b19a06e1b8d09e.1文件(记录body信息)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值