• 使用ReTrofit做缓存(结合上拉加载和下拉刷新)


    1. noCache 不使用缓存,全部走网络

    2. noStore 不使用缓存,也不存储缓存

    3. onlyIfCached 只使用缓存

    4. maxAge 设置最大失效时间,失效则不使用 需要服务器配合

    5. maxStale 设置最大失效时间,失效则不使用 需要服务器配合 感觉这两个类似 还没怎么弄清楚,清楚的同学欢迎留言

    6. minFresh 设置有效时间,依旧如上

    7. FORCE_NETWORK 只走网络

    8. FORCE_CACHE 只走缓存

    结合推酷和简书看

    Cache-Control: no-cache  在请求头中的意思是:不去拿缓存的数据,直接去访问服务器的数据。  在响应头中的意思是:服务器允许客户端缓存,但是必须先验证一下(和 no-store的区别)

    Cache-Control: max-age=300 在请求头中表示:第一次访问服务器获取数据之后,300秒之内再访问时,直接走缓存,超过300秒再去请求服务器

                  在响应头中表示:300秒之内,从服务器的缓存中回给客户端,300秒后从真正的数据中回给客户端

    在响应头中,Cache-Control参数的 no-cache,表示客户端仍然可以缓存,但是缓存时要评估下有效性(?)

    相应的,在响应头中,no-store,表示客户端一定无法缓存,注意两者区别.

      用ReTrofit做缓存时,使用的OkHttp的拦截器,在ReTrofit初始化中进行设置

    //构造函数
    public
    WebControl_Retrofit(){ init(); }
    public void init() {
            Log.d("OkHttp","ReTrofit init");
            HttpLoggingInterceptor logging = new HttpLoggingInterceptor();//添加访问网络的日志
            logging.setLevel(HttpLoggingInterceptor.Level.BODY);//日志级别
            OkHttpClient httpClient = new OkHttpClient();
    
            //缓存路径
            File cacheFile = new File(UIUtils.getContext().getCacheDir().getAbsolutePath(), "HttpCache");
            Cache cache = new Cache(cacheFile, 1024 * 1024 * 100);//缓存文件为100MB
            httpClient.setCache(cache);
    
            Interceptor netInterceptor = new Interceptor() {
                @Override
                public Response intercept(Chain chain) throws IOException {
                    Request request = chain.request();
                    if(!UIUtils.isNetworkReachable(UIUtils.getContext())){//如果网络不可用
                        request=request.newBuilder()
                                .cacheControl(CacheControl.FORCE_CACHE)
                                .build();
                        Log.d("OkHttp","网络不可用请求拦截");
                    }else{//网络可用
                        request = request.newBuilder()
                                .cacheControl(CacheControl.FORCE_NETWORK)
                                .build();
                        Log.d("OkHttp","网络可用请求拦截");
                    }
                    Response response = chain.proceed(request);
                    if(UIUtils.isNetworkReachable(UIUtils.getContext())){//如果网络可用
                        Log.d("OkHttp","网络可用响应拦截");
                        response= response.newBuilder()
                                //覆盖服务器响应头的Cache-Control,用我们自己的,因为服务器响应回来的可能不支持缓存
                                .header("Cache-Control", "public,max-age=2")
                                .removeHeader("Pragma")
                                .build();
                    }else{
    //                    Log.d("OkHttp","网络不可用响应拦截");
    //                    int maxStale = 60 * 60 * 24 * 28; // tolerate 4-weeks stale
    //                    response= response.newBuilder()
    //                            .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
    //                            .removeHeader("Pragma")
    //                            .build();
                    }
                    return response;
    
                }
            };
            httpClient.interceptors().add(netInterceptor);//添加本地缓存拦截器,用来拦截本地缓存
            httpClient.networkInterceptors().add(netInterceptor);//添加网络拦截器,用来拦截网络数据
            httpClient.interceptors().add(logging);  // <-- this is the important line!
    
    
            mRetro = new Retrofit.Builder()
                    .baseUrl(Web_GlobalConstant.SERVER_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(retrofit.RxJavaCallAdapterFactory.create())
                    .client(httpClient)
                    .build();
        }

     ReTrofit是根据请求服务器的URL去创建缓存文件,请求的URL不同,所创建的缓存文件也不同,在发起访问服务器请求时,Retrofit根据URL去找对应的缓存,然后返回缓存的数据

    刷新和加载更多的思路:让服务器给每一条数据做一个时间戳标记,回过来数据时放在Json里,客户端的请求URL中加一个时间戳参数,下拉刷新时,客户端传时间戳为0,表示请求最新的20条数据(假设以20条为单位),请求后ReTrofit根据URL把最新20条数据缓存起来,以请求朋友圈为例子,那么朋友圈缓存文件里只有一个文件,那就是最新的20条数据,并且永远会这样,把传过来的最后一条数据的时间戳记下来,等到上拉加载时,把这个时间戳参数传过去,然后服务器再把这个时间戳对应数据的之后20条数据回过来,如此循环,这样就能保证数据完整性,上拉加载更多的数据不需要缓存,只缓存最新的20条数据,服务器是以时间倒序存储的数据

    做个笔记:static修饰的变量,在应用程序没有完全被清理时,会一直保持引用

    这里是我的GitHub地址,里面有我自己做的一些有用的Demo,适合新手学习,欢迎大家star我的项目 https://github.com/gnehsuy

  • 相关阅读:
    HTTP Status 404
    The error occurred while setting parameters--索引 3 超出范围 sqlserver2008
    hessian不能注入dao的问题解决
    怎么 才能显示Eclipse中Console的全部内容
    java mvc web 项目web.xml头改错了,死活加载不上springMvc的jar
    如何理解andriod中的View和framelayout两个概念
    Type Project has no default.properties file! Edit the project properties to set one.
    shell获取目录下(包括子目录)所有文件名、路径、文件大小
    找出1小时内占用cpu最多的10个进程的shell脚本
    awk统计命令(求和、求平均、求最大值、求最小值)
  • 原文地址:https://www.cnblogs.com/android-yus/p/5280739.html
Copyright © 2020-2023  润新知