OkHttp基礎(chǔ)學習(四),無網(wǎng)絡(luò)讀取本地緩存悉默,有錯誤城豁,待改正

學習資料:

沒有網(wǎng)絡(luò),讀取本地緩存

在手機狀態(tài)欄中抄课,并沒有流量和WIFI聯(lián)網(wǎng)的標志


1. 無網(wǎng)絡(luò)唱星,使用本地緩存

完整Activity代碼:

public class NoNetworkActivity extends AppCompatActivity implements ResultCallback<String> {
    private TextView tv_info;
    private String cachePath;
    private Platform mPlatform;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_no_network);
        //緩存路徑
        String path = Environment.getExternalStorageDirectory().getPath()
                + File.separator + Strings.FILE_PATH + File.separator + Strings.CACHE_PATH;
        File directory = new File(path);
        if (!directory.exists()) {
            if (directory.mkdirs()) ToastUtils.show(NoNetworkActivity.this, "緩存文件夾創(chuàng)建成功");
        }
        cachePath = directory.getPath();
        init();
    }

    /**
     * 初始化
     */
    private void init() {
        mPlatform = Platform.get();
        tv_info = (TextView) findViewById(R.id.no_network_activity_tv);
        request();

    }

    private void request() {
        OkHttpClient okHttpClient = new OkHttpClient
                .Builder()
                .connectTimeout(10, TimeUnit.SECONDS)
                .readTimeout(10, TimeUnit.SECONDS)
                .addNetworkInterceptor(new Interceptor() {//添加網(wǎng)絡(luò)攔截器
                    @Override
                    public Response intercept(Chain chain) throws IOException {
                        Request request = chain.request();
                        Response response = chain.proceed(request);
                        if (isNetworkConnected()) {
                            int maxAge = 60 * 60;// 有網(wǎng) 就1個小時可用
                            return response.newBuilder()
                                    .header("Cache-Control", "public, max-age=" + maxAge)
                                    .build();
                        } else {
                            int maxStale = 60 * 60 * 24 * 7;// 沒網(wǎng) 就1周可用
                            return response.newBuilder()
                                    .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
                                    .build();
                        }
                    }
                })
                .cache(new Cache(new File(cachePath), 30 * 1024 * 1024))//最大 30m
                .build();

        Request request = new Request.Builder().url(Urls.GET_URL).build();

        Call call = okHttpClient.newCall(request);

        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                sendFailResultCallback(e);//失敗回調(diào)
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                //請求結(jié)果
                ResponseBody responseBody = null;
                try {
                    //判斷請求是否取消
                    if (call.isCanceled()) {
                        sendFailResultCallback(new IOException("Request Canceled"));
                        return;
                    }
                    //獲取請求結(jié)果 ResponseBody
                    responseBody = response.body();
                    //獲取字符串
                    String json = responseBody.string();
                    Log.e("activity", json);
                    //成功回調(diào)
                    sendSuccessResultCallback(json);
                } catch (Exception e) {//發(fā)生異常雳旅,失敗回調(diào)
                    sendFailResultCallback(e);
                } finally {//記得關(guān)閉操作
                    if (null != responseBody) {
                        responseBody.close();
                    }
                }
            }
        });

    }

    /**
     * 手機是否聯(lián)網(wǎng)
     */
    private boolean isNetworkConnected() {
         //6.0 之后得使用 getApplicationContext()..getSystemService(...)
         //否則會內(nèi)存泄漏
        ConnectivityManager manager = (ConnectivityManager)  getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetworkInfo = manager.getActiveNetworkInfo();
        return activeNetworkInfo.isConnected();
    }

    /**
     * 網(wǎng)絡(luò)請求失敗
     */
    @Override
    public void sendFailResultCallback(final Exception e) {
        doSomething(new Runnable() {
            @Override
            public void run() {
                String info = "Fail Message --> " + e.getMessage();
                tv_info.setText(info);
            }
        });
    }

    /**
     * 請求成功
     */
    @Override
    public void sendSuccessResultCallback(final String result) {
        doSomething(new Runnable() {
            @Override
            public void run() {
                tv_info.setText(JsonFormatUtils.formatJson(result));
            }
        });
    }
    
    /**
     * UI線程回調(diào)
     */
     
    private void doSomething(Runnable runnable) {
        mPlatform.execute(runnable);
    }
}

cache(Cache,Size):添加緩存,指定緩存路徑和空間大小

當設(shè)備斷網(wǎng)時间聊,通過Interceptor攔截器來進行網(wǎng)絡(luò)訪問,可以直接讀取之前本地緩存

使用addNetworkInterceptor(Interceptor)OkHttpCLient添加一個網(wǎng)絡(luò)攔截器

重寫Interceptor內(nèi)的intercept(Chain)方法攒盈,根據(jù)網(wǎng)絡(luò)狀態(tài),設(shè)置緩存有效期

  • Cache-Control甸饱,緩存控制
  • public沦童,所有網(wǎng)頁信息都緩存
  • max-age,緩存有效期限叹话,在這個期限內(nèi)偷遗,不去再去進行網(wǎng)絡(luò)訪問
  • only-if-cached,只接受緩存的內(nèi)容
  • max-stale驼壶,在設(shè)置期限內(nèi)氏豌,客戶端可以接受過去的內(nèi)容

百度百科中Cache-control說得挺簡單明了


2. Interceptor攔截器

Interceptor是一個接口

源碼:

/*
 * Copyright (C) 2014 Square, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package okhttp3;

import java.io.IOException;

/**
 * Observes, modifies, and potentially short-circuits requests going out and the corresponding
 * responses coming back in. Typically interceptors add, remove, or transform headers on the request
 * or response.
 */
public interface Interceptor {
  Response intercept(Chain chain) throws IOException;

  interface Chain {
    Request request();

    Response proceed(Request request) throws IOException;

    Connection connection();
  }
}

代碼不多,但感覺接口的使用方式热凹,可以學習


攔截器作用:

Interceptors are a powerful mechanism that can monitor, rewrite, and retry
calls. Here's a simple interceptor that logs the outgoing request and the
incoming response

攔截器是一個強大的機制泵喘,可以監(jiān)控,修改般妙,重試 Call請求

個人理解:可以看作是海關(guān)纪铺,高速收費站,對進出的船或車碟渺,進行把控

interceptors

貼個圖鲜锚,不為別的,就是感覺這個圖:簡潔苫拍,優(yōu)雅芜繁,大方,逼格


攔截有兩種:Application InterceptorNetwork Interceptor

一個灰色矩形塊塊就是一個Interceptor绒极,一個OkHttpClient可以添加多個Interceptor攔截器

  • Application Interceptor主要多用于查看請求信息或者返回信息骏令,如鏈接地址,頭信息垄提,參數(shù)等

  • Network Interceptor多用于對請求體Request或者響應體Response的改變榔袋,緩存處理用這個

暫時也就知道這么多了,Interceptor.Chain中3個方法具體做了啥塔淤,到了后面學習OkHttp工程流程摘昌,再學習了解


2.1 Application Interceptor 簡單使用

代碼:直接加在OkHttpClient中的addNetworkInterceptor前就可以

     .addInterceptor(new Interceptor() {
             @Override
             public Response intercept(Chain chain) throws IOException {
             Request request = chain.request();

             long t1 = System.nanoTime();
             String info_1 = String.format("Sending request %s on %s%n%s", request.url(),
                 chain.connection(), request.headers());
                Log.e("info1", "-->" + info_1);

                Response response = chain.proceed(request);
                long t2 = System.nanoTime();
                String info_2 = String.format("Received response for %s in %.1fms%n%s".toLowerCase(),
             response.request().url(), (t2 - t1) / 1e6d, response.headers());
             Log.e("info2", "-->" + info_2);
             return response;
         }
     })

輸出Log信息:

Application Interceptor 攔截信息

3. 最后

有錯誤,請指出

共勉 :)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末高蜂,一起剝皮案震驚了整個濱河市聪黎,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖稿饰,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锦秒,死亡現(xiàn)場離奇詭異,居然都是意外死亡喉镰,警方通過查閱死者的電腦和手機旅择,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來侣姆,“玉大人生真,你說我怎么就攤上這事∞嘧冢” “怎么了柱蟀?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蚜厉。 經(jīng)常有香客問我长已,道長,這世上最難降的妖魔是什么昼牛? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任术瓮,我火速辦了婚禮,結(jié)果婚禮上贰健,老公的妹妹穿的比我還像新娘胞四。我一直安慰自己,他們只是感情好伶椿,可當我...
    茶點故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布撬讽。 她就那樣靜靜地躺著,像睡著了一般悬垃。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上甘苍,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天尝蠕,我揣著相機與錄音,去河邊找鬼载庭。 笑死看彼,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的囚聚。 我是一名探鬼主播靖榕,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼顽铸!你這毒婦竟也來了茁计?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤谓松,失蹤者是張志新(化名)和其女友劉穎星压,沒想到半個月后践剂,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡娜膘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年逊脯,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片竣贪。...
    茶點故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡军洼,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出演怎,到底是詐尸還是另有隱情匕争,我是刑警寧澤,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布颤枪,位于F島的核電站汗捡,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏畏纲。R本人自食惡果不足惜扇住,卻給世界環(huán)境...
    茶點故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望盗胀。 院中可真熱鬧艘蹋,春花似錦、人聲如沸票灰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽屑迂。三九已至浸策,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間惹盼,已是汗流浹背庸汗。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留手报,地道東北人蚯舱。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像掩蛤,于是被迫代替她去往敵國和親枉昏。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,960評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 緩存的一般思路 下面是我理解的網(wǎng)絡(luò)請求框架的緩存基本實現(xiàn)揍鸟。大致的過程是有緩存用緩存的數(shù)據(jù)兄裂,沒緩存發(fā)起http請求取...
    原件閱讀 2,809評論 3 12
  • MVP+okHttp+Retrofit+RxJava+Glide+Dagger 是現(xiàn)在最流行的一套技術(shù)框架, MV...
    EmanLu閱讀 1,800評論 0 3
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn)懦窘,斷路器前翎,智...
    卡卡羅2017閱讀 134,657評論 18 139
  • Interceptors are a powerful mechanism that can monitor, r...
    漢之風云閱讀 50,381評論 9 98
  • 在凝重的夜晚, 我寫著對你的印象畅涂, 究竟是模糊的港华, ...
    慕寒君閱讀 825評論 0 0