现在应该有许多人都是使用okhttp来作为项目的网络请求的底层库,那么,还有人在沿用着对每个请求在执行前后手动打印一下参数及地址这种古老的日志打印方式吗?okhttp的灵活而强大的特点之一,就是其提供了一个拦截器接口,使得我们在打印日志时极为方便,并且对我们的接口代码无入侵性。
本篇文章介绍一个okhttp3的日志打印库,无论是使用古老方式来打印日志的,还是使用square官方okhttp3的日志库的,都可以一看。
okhttp3-loginterceptor是用于okhttp3的一个日志打印库,小巧轻量,相比square提供的okhttp3的logging-interceptor,它对每个请求和响应都进行编号 ,并且对于json的请求或响应内容,还将打印出格式化的JSON内容,而除了依赖okhttp3之外,它不会添加任何其他第三方依赖。那么它是如何小巧轻量而又不会向项目引入其他依赖的呢?等下我们在文中会提到,下面先开始介绍它的使用。
快速入门
okhttp3-loginterceptor在github上的项目地址为:https://github.com/parkingwang/okhttp3-loginterceptor。引入方式很简单,只需几行代码。如下:
声明依赖
添加依赖,以下的latest.integration
建议换为当前最新版本的具体版本号。
compile 'com.parkingwang:okhttp3-loginterceptor:latest.integration'
添加代码
然后在创建OkHttpClient
对象的代码中添加其拦截器实例,代码如下:
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addInterceptor(new LogInterceptor()).build();
这样就完成了。然后你就可以看到类似这样的日志了:
W/OkHttp: [4 request]--> GET https://api.github.com/users/defunkt http/1.1
W/OkHttp: [4 request]--> END GET
W/OkHttp: [5 request]--> GET https://api.github.com/zen http/1.1
W/OkHttp: [5 request]--> END GET
W/OkHttp: [6 request]--> GET https://api.github.com/users/msdx http/1.1
W/OkHttp: [6 request]--> END GET
W/OkHttp: [4 response]<-- 200 OK https://api.github.com/users/defunkt (1335ms)
W/OkHttp: [4 response]Server: GitHub.com
W/OkHttp: [4 response]Date: Thu, 12 Jan 2017 04:01:43 GMT
W/OkHttp: [4 response]Content-Type: application/json; charset=utf-8
W/OkHttp: [4 response]Transfer-Encoding: chunked
文章这就结束了?当然不,既然是专门介绍的文章当然得好好写写。
详细介绍
适当地添加日志拦截器
首先,我们打印日志一般都是在debug的时候才需要,对于release即发布出去的版本,是不需要打印请求的日志的,所以通常我们会这样写代码:
final OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
if (BuildConfig.DEBUG) {
clientBuilder.addInterceptor(new LogInterceptor());
}
return clientBuilder
//.XXX 省略一大堆设置其他参数的代码
.build();
关于JSON格式化输出
前面提到,okhttp3-loginterceptor除了okhttp3之外,不会向项目添加其他第三方依赖,尽量做到小巧轻量。所以当判断请求或响应的contentType的内容为JSON数据而尝试格式化输出JSON内容时,是采用反射的方式。在第一次调用JSON格式化的时候,会判断当前使用的是哪一个JSON解析库,然后调用其相关方法来格式化JSON。目前支持常用的JSON解析库,包括:gson, fastjson, moshi, org.json。当你的项目不包含以上这些库时,则不会进行格式化的JSON数据输出。
混淆规则
okhttp3-loginterceptor由于使用反射来调用前面所提到的json解析库,而本身并没有对它们声明依赖。所以需要添加以下的混淆规则:
-dontwarn com.parkingwang.okhttp3.LogInterceptor.formatter.*
最后
okhttp3-loginterceptor是我基于需要的功能,参考okhttp3-logging-interceptor的代码而封装的一个库。
首先,我们与服务器的数据交互使用json方式比较多,在开发或调试时需要更能直观地查看json数据,所以我封装了格式化输出json数据的功能。
其次,在应用中,经常是多个请求同时进行。通过日志中的线程名来判断哪一行是属于哪个响应,对应于哪个请求相当不便,所以我在每一行添加了一个前缀,也是为了更直观地查看日志。
我设想的是让它只做最需要的事,所以没添加也没打算添加其他一些日志库的酷炫输出日志格式的功能。