zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Android混淆代码的方法
    Android开发如何在4.0及以上系统中自定义TitleBar
    设置按钮的selector
    MD5加密(Android里和Java SE里是一样的)
    Android中图片实现按钮点击效果
    Handler消息传递机制
    ContentProvider的使用
    操作Sqlite数据库
    使用Pull解析器读取XML文件
    Android添加事件的四种方法
  • 原文地址:https://www.cnblogs.com/zhang-cb/p/6076655.html
Copyright © 2011-2022 走看看