Android 开发之Okhttp网络请求日志打印
这里写自定义目录标题
- Android 开发之Okhttp 网络请求日志打印
- OkHTTP网络日志打印
Android 开发之Okhttp 网络请求日志打印
网络请求是开发的日常工作内容之一,网络日志打印也有很多要注意及优化的部分,本文分享我在开发过程中编写的OkHttp网络请求日志打印方法实现
OkHTTP网络日志打印
直接用OKHTTP请求接口的方式
- 要在接口请求的回调方法内进行信息获取和打印 ,即在自定义的Callback实现类或实现对象中
public abstract class MyStringCallBack<T> implements CallBack{@Overridepublic void onFailure(Call call, final IOException e) {}@Overridepublic void onResponse(Call call, final Response response) throws IOException {}}
当请求流程顺利进行完之后 再onResponse中进行获取网络请求信息和返回的信息打印集合;
因为onResponse和onFailure都有Call对象,并且call能获取到请求信息,所以创建一个方法,用来获取网络请求信息private ArrayList<String> getLogRequstList(Call call) throws IOException {Request request = call.request();ArrayList<String> logArrays = new ArrayList<>();//声明集合用来保存要打印的log信息RequestBody requestBody = request.body();boolean hasRequestBody = requestBody != null;//获取请求的方法,地址String requestStartMessage = "--> " + request.method() + ' ' + URLDecoder.decode(request.url().toString() ,"UTF-8")+ ' ' ;if ( hasRequestBody) {requestStartMessage += " (" + requestBody.contentLength() + "-byte body)";}logArrays.add(requestStartMessage);//添加到集合中Headers headers = request.headers();logArrays.add("---------->REQUEST HEADER<----------");for (int i = 0, count = headers.size(); i < count; i++) {//header信息logArrays.add(headers.name(i) + ": " + headers.value(i));}if (!hasRequestBody) {//是否有body请求参数logArrays.add("--> END " + request.method());} else if (bodyEncoded(request.headers())) {logArrays.add("--> END " + request.method() + " (encoded body omitted)");} else {Buffer buffer = new Buffer();requestBody.writeTo(buffer);Charset charset = UTF8;MediaType contentType = requestBody.contentType();if (contentType != null) {charset = contentType.charset(UTF8);}if (isPlaintext(buffer)) {logArrays.add("---------->REQUEST BODY<----------");//添加请求的body打印信息logArrays.add(URLDecoder.decode(buffer.readString(charset), "UTF-8"));logArrays.add("--> END " + request.method()+ " (" + requestBody.contentLength() + "-byte body)");} else {logArrays.add("--> END " + request.method() + " (binary "+ requestBody.contentLength() + "-byte body omitted)");}}return logArrays; }
再创建一个返回信息打印信息方法
/** * * 获取返回的log信息 * @param response * @return * @throws IOException */ private ArrayList<String> getLogResponseList( Response response) throws IOException { String requestTime = response.request().header("requestTime");//为了计算耗时,在请求头中添加了请求时间long tookMs =System.currentTimeMillis() - (requestTime == null ? 0 : Long.parseLong(requestTime));ArrayList<String> logArrays = new ArrayList<>();//打印信息集合ResponseBody responseBody = response.body();long contentLength = responseBody.contentLength();//此处不用betys()以免response关闭报错String bodySize = contentLength != -1 ? contentLength + "-byte" : "unknown-length";logArrays.add("<-- response code:" + response.code() + " message:" + response.message()+" contentlength:"+bodySize );logArrays.add("<-- response url:"+URLDecoder.decode(response.request().url().toString(),"UTF-8") );logArrays.add("<-- costtimes : (" + tookMs + "ms" + ')');if ( !HttpHeaders.hasBody(response)) {logArrays.add("<-- END HTTP");} else if (bodyEncoded(response.headers())) {logArrays.add("<-- END HTTP (encoded body omitted)");} else {BufferedSource source = responseBody.source();source.request(Long.MAX_VALUE); // Buffer the entire body.Buffer buffer = source.buffer();Charset charset = UTF8;MediaType contentType = responseBody.contentType();if (contentType != null) {charset = contentType.charset(UTF8);}if (!isPlaintext(buffer)) {logArrays.add("");logArrays.add("<-- END HTTP (binary " + buffer.size() + "-byte body omitted)");return logArrays;}logArrays.add("---------->RESPONSE BODY<----------");if (contentLength != 0) {//返回的参数logArrays.add(GsonUtils.retractJson(buffer.clone().readString(charset)));}logArrays.add("<-- END HTTP (" + buffer.size() + "-byte body)"); } return logArrays;}
最后创建打印方法,由于网络请求不在同一个线程,为了避免打印的信息错乱,多个请求返回信息输出不对应,我们要用到synchronized关键字来保证线程安全,也就是依次执行。为了保证可读性,还添加了视图框
`
`/*** 打印log* @param list*/ private synchronized void printLog(ArrayList<String> list,boolean info){int length = 0 ;//计算每行最长的长度StringBuilder sb = new StringBuilder();for(String str : list){if(str.indexOf("\n")>-1){//有换行的拆分处理String[] split = str.split("\n");for(String s : split){s = s.replace("\t"," ");//缩进替换空格if(length<s.length()){length = s.length();}}}else{if(length<str.length()){length = str.length();}}}length+=14;//左右间距String head = "HTTP REQUEST START";sb.append(" \n\n\n"+"\n");//打印头部String logHead = "┏"+getEmptyStr((length-head.length())/2,"━")+head+getEmptyStr((length-head.length())/2,"━")+"┓";sb.append(logHead+"\n");//打印内容for(String str : list){String logStr = "";if(str.indexOf("\n")>-1){//内部换行替换splitStr(str,logHead.length(),sb);}else{if(str.length()> logHead.length()){outOflength(str,logHead.length(),sb);}else {logStr = "┃ " + str + getEmptyStr((length - 14 - str.length()), " ");//处理中文间距,保证打印无偏差sb.append(logStr + getEmptyStr((logHead.length() - logStr.length() - 1 - hasCNchar(logStr)), " ") + "┃ \n");}}}String end = "HTTP REQUEST END";//打印结尾sb.append("┗"+getEmptyStr((length-end.length())/2,"━")+end+getEmptyStr((length-end.length())/2,"━")+"┛\n");sb.append(" \n\n\n");//Logger.DEFAULT.log(sb.toString());//打印log,避免多个log语句,导致log输出时其他线程的log输出切入此输出阵列内String[] split = sb.toString().split("\n");for(String str : split){if(info) {MyLog.i(TAG, str);}else{MyLog.e(TAG, str);}} }`
接下来看一下打印效果
到此 功能就写完了,我把源码放在一个Android开发分享的项目里,项目会陆续上传我自己写的多种工具类及框架,本文相关的 源码地址 http://www.hefan.space:1001/blob/share%2Fandroid.git/master/app%2Fsrc%2Fmain%2Fjava%2Fcom%2Frunt%2Fsharedcode%2Futils%2FPrintLogUtils.java;
也可以加QQ群交流技术
最后推荐一个我自己写的MVVM开源项目《Open MVVM》
(加群请进入文章结尾查看群号)
有问题请私信,留言,或者发送邮件到我扣扣邮箱 qingingrunt2010
Android 开发之Okhttp网络请求日志打印相关推荐
- Android开发之HttpClient网络请求以Json方式提交Post请求代码
public class PayHttpUtils {/*** @param url 请求的网址*/public static String GetSingleCabCollect(String ur ...
- Android开发之http网络请求返回码问题集合。
2019独角兽企业重金招聘Python工程师标准>>> HTTP状态码(HTTP Status Code) 一些常见的状态码为: 200 - 服务器成功返回网页 404 - 请 ...
- Flutter开发之HTTP网络请求:Http库(27)
第三方库 http实现get,post网络请求. http库文档地址:https://pub.dev/packages/http#-installing-tab- 添加依赖库 Add this to ...
- Flutter开发之HTTP网络请求:HttpClient(26)
本文根据 在Flutter中发起HTTP网络请求 编写 对于入门的同学来说,使用的是用dart io中的HttpClient发起的请求,能让我快速接入HTTP网络请求.但HttpClient本身功能较 ...
- Android开发之APN网络切换
原文:http://www.cnblogs.com/hanyonglu/archive/2012/03/29/2423298.html 本文介绍Android平台中关于APN网络切换的相关知识以及如何 ...
- Flutter开发之HTTP网络请求:dio库(28)
dio是Flutter中文网开源的一个强大的Dart Http请求库,支持Restful API.FormData.拦截器.请求取消.Cookie管理.文件上传/下载.超时等- 第三方库 dio实现g ...
- Flutter开发之Http网络请求
简介 Http网络请求是一门开发语言里比较常用和重要的功能,主要用于资源访问.接口数据请求和提交.上传下载文件等等操作,Http请求方式主要有:GET.POST.HEAD.PUT.DELETE.TRA ...
- Android中使用logger打印完整的okhttp网络请求和响应的所有相关信息(请求行、请求头、请求体、响应行、响应行、响应头、响应体)
如果你的项目中的网络请求库是Retrofit的话,他的底层封装的是OkHttp,通常调试网络接口时都会将网络请求和响应相关数据通过日志的形式打印出来.OkHttp也提供了一个网络拦截器okhttp-l ...
- Android okHttp网络请求之缓存控制Cache-Control
前言: 前面的学习基本上已经可以完成开发需求了,但是在项目中有时会遇到对请求做个缓存,当没网络的时候优先加载本地缓存,基于这个需求我们来学习一直okHttp的Cache-Control. okHttp ...
最新文章
- 干货丨从概念到案例:初学者须知的十大机器学习算法
- opensuse 升级内核
- 二维动画作品_动画设计丨从设计到制作,你不知道的东西还有很多......
- 【Qt】QLayoutItem类
- mysql5.7初始密码查看及密码重置
- 网不好怎么办?TLS握手带宽直降80%,BabaSSL是怎么做到的?| 龙蜥技术
- app index.html,create-react-app搭建react开发环境中的public/index.html.
- BLM业务战略规划的底层逻辑是什么?
- 用u盘装linux系统的操作全程图解,笔者教你用u盘装系统的操作全程图解
- 随机梯度下降算法SGD
- C语言经典面试题100道(校对详解版)
- android 弹跳动画效果下载,SpringyFX-SpringyFX(MG弹跳动画制作AE脚本)下载 v1.1官方版--pc6下载站...
- BZOJ3787 gty的文艺妹子序列 【树状数组】【分块】
- 在局域网内互传文件的方法
- 一个刚入行而又不甘于平庸的程序猿2019个人总结
- 【更新7】ARCH和GARCH模型
- 几款软件,内有很多人求而不得的破解版TeamViewer
- VLAN trunk扩展 MUXVLAN 原理与实验
- php开发勋章插件,勋章中心 2.0 For Discuz!7.0
- 【株洲出差】回记人生第一次出差之旅
热门文章
- 拼多多关键词搜索接口,item_search - 根据关键词取拼多多商品列表接口解决方案
- 从简历被刷到拿字节跳动 offer,我花了一年时间
- 海盗分椰子c语言编程,水手分椰子——迭代法、递归解题(示例代码)
- Android使用CameraX打开相机拍照简单使用
- bbr中的缩放因子BW_SCALE/BBR_SCALE
- Unity_触摸屏_实现360序列帧
- 运维工程师的发展前景如何?
- 后出海时代:“陡坡式增长”失速,“阶梯式增长”到来
- 6:求指定范围内的素数
- Android实战(MediaPlayer填坑)