Okhttp3日志采集功能


原文地址以示尊重:http://www.jianshu.com/p/d836271b1ae4

日志采集是一個APP必備的功能,可以方便開發人員快速定位問題,解決問題,那么我們在使用okhttp的時候應該怎樣添加日志功能呢?

直接上干貨

private class LogInterceptor implements Interceptor {
        @Override
        public okhttp3.Response intercept(Chain chain) throws IOException {
            Request request = chain.request();
            Log.v("zcb", "request:" + request.toString());
            long t1 = System.nanoTime();
            okhttp3.Response response = chain.proceed(chain.request());
            long t2 = System.nanoTime();
            Log.v("zcb", String.format(Locale.getDefault(), "Received response for %s in %.1fms%n%s",
                    response.request().url(), (t2 - t1) / 1e6d, response.headers()));
            okhttp3.MediaType mediaType = response.body().contentType();
            String content = response.body().string();
            Log.i("zcb", "response body:" + content);
            return response.newBuilder()
                    .body(okhttp3.ResponseBody.create(mediaType, content))
                    .build();
        }
    }


    ...
    OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .addInterceptor(new LogInterceptor())
                .build();

 

首先我們實現了一個攔截器LogInterceptor,里面做了三件事情:打印request內容->執行request->打印response內容,過程簡單清晰。但是有一個地方需要注意一下,在調用了response.body().string()方法之后,response中的流會被關閉,我們需要創建出一個新的response給應用層處理。手快的同學已經敲完了代碼並驗證了一遍,發現攔截器中能獲取到body的內容,但是在攔截器外面就獲取不到了。

這是為什么呢?Talk is cheap show me the code。先看一下response.body().string()的實現

public final String string() throws IOException {
    return new String(bytes(), charset().name());
  }

string()調用了bytes()來獲取內容

public final byte[] bytes() throws IOException {
    //省略部分代碼
    BufferedSource source = source();
    byte[] bytes;
    try {
      bytes = source.readByteArray();
    } finally {
      Util.closeQuietly(source);
    }
    //省略部分代碼
    return bytes;
  }

 

 

bytes()方法中先得到了BufferedSource,然后將BufferedSource中的內容讀取出來,最后將BufferedSource中的文件流關閉,似乎並沒有什么問題。等等,我們在攔截器中將BufferedSource中的文件流關閉,而在ResponseBody中沒有相應的數據緩存,所以我們在攔截器外部再想獲取body的內容就失敗了,一切終於真相大白。

可以看到,我們在攔截器中相當於手動處理了網絡請求的整個過程,這就意味着在攔截器中可以做非常多的事情,例如虛擬一個返回結果等等,這些就不是本文的內容了。

Update
使用Logging Interceptor可以很輕松的實現日志采集功能,具體細節參考

參考內容:
[1]. https://github.com/square/okhttp/wiki/Interceptors

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM