OkHttp高效開發(fā)介紹

一.開啟OKHttp緩存
OKHTTP有自己的網絡緩存機制,針對GET請求 有網時 獲取數(shù)據(jù)并緩存,沒網時會看是否有緩存,有緩存則返回緩存的數(shù)據(jù)。
1.設置緩存

  /**
  * 設緩存有效期為兩天
  */
   private static final long CACHE_STALE_SEC = 60 * 60 * 24 * 2;
  // 指定緩存路徑,緩存大小100Mb
    Cache cache = new Cache(new File(BaseApplication.context().getCacheDir(), "HttpCache"),
                 1024 * 1024 * 50);

2.設置攔截器(緩存)

 * 云端響應頭攔截器,用來配置緩存策略
 * Dangerous interceptor that rewrites the server's cache-control header.
 */
private Interceptor mRewriteCacheControlInterceptor = new Interceptor() {
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        if (!NetWorkUtils.isNetConnected(BaseApplication.getAppContext())) {
            request = request.newBuilder()
                    .cacheControl(CacheControl.FORCE_CACHE)
                    .build();
        }
        Response originalResponse = chain.proceed(request);
        if (NetWorkUtils.isNetConnected(BaseApplication.getAppContext())) {
            //有網的時候讀接口上的@Headers里的配置,你可以在這里進行統(tǒng)一的設置
            String cacheControl = request.cacheControl().toString();
            return originalResponse.newBuilder()
                    .header("Cache-Control", cacheControl)
                    .removeHeader("Pragma")
                    .build();
        } else {
            return originalResponse.newBuilder()
                    .header("Cache-Control", "public, only-if-cached, max-stale=" + CACHE_STALE_SEC)
                    .removeHeader("Pragma")
                    .build();
        }
    }
};

3.加上網絡超時配置就可以了

    OkHttpClient okHttpClient = new OkHttpClient.Builder()
             //網絡超時
            .readTimeout(5000, TimeUnit.MILLISECONDS)
            .connectTimeout(5000,TimeUnit.MILLISECONDS)
            .writeTimeout(5000,TimeUnit.MILLISECONDS)
             //網絡緩存
            .addInterceptor(mRewriteCacheControlInterceptor)
            .addNetworkInterceptor(mRewriteCacheControlInterceptor)
             //緩存
            .cache(cache)
            .build();

二.觀察HTTP請求&響應數(shù)據(jù)的方法

  1. 添加 HttpLoggingInterceptor

     HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
      //包含header、body數(shù)據(jù)
    loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
    //在build OkHttpClient的時候加入Log攔截器
    OkHttpClient.Builder().addInterceptor(loggingInterceptor)
    

HttpLoggingInterceptor的效果如下圖,開發(fā)時如果需要看整個App的所有請求及相應,可以使用okhttp關鍵字過濾


注意!這樣設置 有時會有問題!??!
(1).會報錯

   java.lang.NoSuchMethodError: No virtual method log(Ljava/lang/String;)V in class  Lokhttp3/internal/Platform; or its super classes

把retrofit依賴包改為2.0.1后,問題迎刃而解

(2).打印不出網絡請求日志 可以按如下修改

   HttpLoggingInterceptor logInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
                    @Override
                    public void log(String message) {
                        Log.e("okhttp", message);
                    }
                });

2.自定義Interceptor

// 打印返回的json數(shù)據(jù)攔截器
private Interceptor mLoggingInterceptor = new Interceptor() {
    @Override
    public okhttp3.Response intercept(Chain chain) throws IOException {

        Request request = chain.request();
        Request.Builder requestBuilder = request.newBuilder();
        Request signedRequest = requestBuilder
                .build();

        okhttp3.Response response = chain.proceed(signedRequest);

        MediaType contentType = null;
        String bodyString = null;
        if (response.body() != null) {
            contentType = response.body().contentType();
            bodyString = response.body().string();
        }
            // 注意!
            // 我只打印了 GET POSt 方法
        switch (request.method()) {
            case "GET":
                Log.e("retrofit-->",
                        "GET "+ signedRequest.url()+" -->"+
                                bodyString);
                break;
            case "POST":
                Log.e("retrofit-->",
                        "POST "+ signedRequest.url()+" -->"+
                                bodyToString(signedRequest)+" -->"+
                                bodyString);
                break;
        }
        if (response.body() != null) {
            // 深坑!
            // 打印body后原ResponseBody會被清空,需要重新設置body
            ResponseBody body = ResponseBody.create(contentType, bodyString);
            return response.newBuilder().body(body).build();
        } else {
            return response;
        }
    }
 };   
private static String bodyToString(final Request request){
    try {
        final Buffer buffer = new Buffer();
        request.body().writeTo(buffer);
        return buffer.readUtf8();
    } catch (final IOException e) {
        return "did not work";
    }
}

//在build OkHttpClient的時候加入Log攔截器

OkHttpClient.Builder().addInterceptor(mLoggingInterceptor );

3.Facebook強大的監(jiān)測工具:Stetho(有興趣的可以多看看 Stetho 這里只講攔截)
(1) 在build OkHttpClient時需要添加網絡攔截器

      OkHttpClient.Builder().addNetworkInterceptor(new StethoInterceptor())

(2) 在Application的OnCreate中初始化

    //FaceBook調試器,可在Chrome調試網絡請求,查看SharePreferences,數(shù)據(jù)庫等
   Stetho.initializeWithDefaults(this);

(3) 連接手機,在Chrome中打開chome://inspect/#devices
看到如下界面,則代表監(jiān)測成功,如果沒有App顯示,那應該就是忘了在Application中初始化Stetho

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容