Retrofit2.0+okhttp3實現緩存

參考文章:Retrofit2.0+okhttp3緩存機制以及遇到的問題

參考文章 : 使用Retrofit和Okhttp實現網絡緩存。無網讀緩存,有網根據過期時間重新請求

參考文章 : okhttp3 retrofit2 緩存問題

我是按照上面文章的思路,把緩存加入到自己的項目

  • 首先就是思路和基本基本一樣的

然後就是我自己在弄的時候發現一些問題

Fatal Exception thrown on Scheduler.Worker thread

出現這個問題的主要原因就是Retrofit 和OKHttp 的版本問題
我自己用到的 Retrofit2的版本是2.1.0版本,也就是最新的, OKHttp 3的版本是3.4.0 但是這樣的組合就是出現了問題,

java.lang.IllegalStateException: Fatal Exception thrown on Scheduler.Worker thread.
       at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:54)
       at android.os.Handler.handleCallback(Handler.java:739)
       at android.os.Handler.dispatchMessage(Handler.java:95)
       at android.os.Looper.loop(Looper.java:145)
       at android.app.ActivityThread.main(ActivityThread.java:5938)
       at java.lang.reflect.Method.invoke(Method.java)
       at java.lang.reflect.Method.invoke(Method.java:372)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1389)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1184)

在網上也看了好多解決辦法,這類的問題發現的也不多,網上的辦法也不好使,然後就想到了版本問題

我目前有就兩種的解決方案,第一種就是更改對應的版本

我現在使用的版本目前是沒有問題的

    //compile 'com.squareup.okhttp3:okhttp:3.4.1'
    compile 'com.squareup.okhttp3:logging-interceptor:3.1.2'
    compile 'com.squareup.retrofit2:adapter-rxjava:2.0.1'
    compile 'com.squareup.retrofit2:converter-gson:2.0.1'
    //TODO換這個版本就沒問題  否則會出現 線程調度異常
    compile 'com.squareup.okhttp3:okhttp:3.0.1'

然後還有一種解決方案,昨天一不小心就可以了,但是寫Okhttp緩存的時候有一次出現了類似的問題,我先貼出來(我覺得還是版本的問題更大一些)

o.subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(subscriber);

就是這樣

  • 然後就是我自己的代碼,主要還是參考網絡上很多很多文章

緩存的主要目的還是在沒有網絡的情況不至於一片白花花的view,然後就是不用每次都請求下載數據

我們還是用OkHttp緩存

上面文章都很明白我直接上代碼就OK
首先就是需要添加addInterceptor和 addNetworkInterceptor這兩個
這兩個現在要必須都設置才能緩存否則的話不行,其他依賴版本的我也沒有試

先說添加的Interceptor
這個主要是設置有網就去網絡,沒網就讀取本地的緩存

 /**
     * 設置返回數據的  Interceptor  判斷網絡   沒網讀取緩存
     */
    public Interceptor getInterceptor(){
        return new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                Request request = chain.request();
                if (!APPNetWork.isNetworkConnected(App.getIntense())) {
                    request = request.newBuilder()
                            .cacheControl(CacheControl.FORCE_CACHE)
                            .build();
                }
                return chain.proceed(request);
            }
        };
    }

另外一個就是NetWorkInterceptor

 /**
     * 設置連接器  設置緩存
     */
    public Interceptor getNetWorkInterceptor (){
        return new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                Request request = chain.request();
                Response response = chain.proceed(request);
                if (APPNetWork.isNetworkConnected(App.getIntense())) {
                    int maxAge = 0 * 60;
                    // 有網絡時 設置緩存超時時間0個小時
                    response.newBuilder()
                            .header("Cache-Control", "public, max-age=" + maxAge)
                            .removeHeader("Pragma")
                            .build();
                } else {
                    // 無網絡時,設置超時爲1周
                    int maxStale = 60 * 60 * 24 * 7;
                    response.newBuilder()
                            .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
                            .removeHeader("Pragma")
                            .build();
                }
                return response;
            }
        };
    }

最後看一下client設置進去就行了

                .addNetworkInterceptor(getNetWorkInterceptor())
                .addInterceptor(getInterceptor())


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章