Android OKHttp 可能你从来没用过的拦截器 【实用推荐】(1)

明明是服务端的接口数据错误,而QA(测试)第一个找到的可能是客户端开发的你,为什么这个页面出现错误了?

而作为客户端开发的你,可能要拿出测试机连上电脑,打一下Log,看一下到底返回了什么数据,导致页面错误。

或者高级一点的QA,会自己打Log或者连接抓包工具看一下服务端返回的具体数据,然后把Bug提给对应的人,而大多数公司的业务测试,都仅仅是测试业务,不管技术层的。我司的大部分QA,属于外派来的,一般也只测试业务,每次有问题,都先找客户端。

场景二

你现在正在外面做地铁,产品或者你领导突然给你反馈,你之前做的那块业务,突然线上跑不起来了,不行了。你一想,这肯定是服务端的问题啊,但是怎么证明呢?

场景三

服务端上个线,每次都需要客户端加班配合,说有问题,可以及时帮助排查问题。

推荐一个小工具

说了这么多,就是缺少一个端上的抓包小工具,来查看服务端的数据是否有问题,今天推荐的是一个基于OKHttp的抓包工具。 部分截图如下

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

支持功能

  • 自带分类接口
  • 抓包数据以时间为纬度,默认存储到手机缓存下 /Android/Data/包名/Cache/capture/ 下
  • 支持Http/Https协议的抓包,分类请求方式/请求URL/请求Header/请求体/响应状态/响应Header/响应体
  • 支持一键复制对应的状态
  • 响应体如果是JSON,支持自动格式化
  • 抓包数据,默认缓存一天

Github地址

代码已经托管到Github 地址:github.com/DingProg/Ne…

快速接入

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

](https://jitpack.io/#DingProg/NetworkCaptureSelf)

allprojects {
repositories {
maven { url ‘https://jitpack.io’ }
}
}

dependencies {
debugImplementation ‘com.github.DingProg.NetworkCaptureSelf:library:v1.0.1’
releaseImplementation ‘com.github.DingProg.NetworkCaptureSelf:library_no_op:v1.0.1’
}

在你的全局OkHttp中添加 Interceptor

new OkHttpClient.Builder()
.addInterceptor(new CaptureInfoInterceptor())
.build();

原理及涉及知识详解

作为Android开发,说到OKHttp的Interceptor,肯定熟悉不过了。那么你对 Interceptor 又了解多少呢?你都使用过那些OKHttp的 Interceptor呢?

我们先来看一下最近滴滴很火的哆啦A梦

DoraemonKit

长下面这个样子

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

其中关于网络模块OK Http的监听如下

OkHttpClient client = new OkHttpClient().newBuilder()
//用于模拟弱网的拦截器
.addNetworkInterceptor(new DoraemonWeakNetworkInterceptor())
//网络请求监控的拦截器 ,用于网络流量监听等
.addInterceptor(new DoraemonInterceptor()).build();

这里举例说一下弱网模拟

弱网模拟

看一下他的实现代码

public class DoraemonWeakNetworkInterceptor implements Interceptor {

@Override
public Response intercept(Chain chain) throws IOException {
if (!WeakNetworkManager.get().isActive()) {
Request request = chain.request();
return chain.proceed(request);
}
final int type = WeakNetworkManager.get().getType();
switch (type) {
case WeakNetworkManager.TYPE_TIMEOUT:
//超时
final HttpUrl url = chain.request().url();
throw WeakNetworkManager.get().simulateTimeOut(url.host(), url.port());
case WeakNetworkManager.TYPE_SPEED_LIMIT:
//限速
return WeakNetworkManager.get().simulateSpeedLimit(chain);
default:
//断网
throw WeakNetworkManager.get().simulateOffNetwork(chain.request().url().host());
}
}
}

实现一个OkHttp的Intercepter,根据不同的状态来进行延迟,例如如下的模拟超时

/**

  • 模拟超时
  • @param host
  • @param port
    */
    public SocketTimeoutException simulateTimeOut(String host, int port) {
    SystemClock.sleep(mTimeOutMillis);
    return new SocketTimeoutException(String.format(“failed to connect to %s (port %d) after %dms”, host, port, mTimeOutMillis));
    }

根据Interceptor 可以干很多事情,那么Interceptor到底是什么样的原理呢?

Interceptor原理

先看一下Interceptor的原型

public interface Interceptor {
Response intercept(Chain chain) throws IOException;
}

再看一下OkHttp源码,可以知道,我们的请求最终都会被调用到RealCall中,并执行到如下代码

@Override protected void execute() {
boolean signalledCallback = false;
try {
Response response = getResponseWithInterceptorChain();
}

}

Response getResponseWithInterceptorChain() throws IOException {
// Build a full stack of interceptors.
List interceptors = new ArrayList<>();
interceptors.addAll(client.interceptors());
interceptors.add(retryAndFollowUpInterceptor);
interceptors.add(new BridgeInterceptor(client.cookieJar()));
interceptors.add(new CacheInterceptor(client.internalCache()));
interceptors.add(new ConnectInterceptor(client));
if (!forWebSocket) {
interceptors.addAll(client.networkInterceptors());
}
interceptors.add(new CallServerInterceptor(forWebSocket));

Interceptor.Chain chain = new RealInterceptorChain(
interceptors, null, null, null, 0, originalRequest);
return chain.proceed(originalRequest);
}

在getResponseWithInterceptorChain 添加了很多OkHttp自定义的拦截器,其中有重定向,Cache,连接请求,发起请求到服务端等。我们来看一下最后几行 代码,RealInterceptorChain是一个Interceptor.Chain类型,并执行chain.proceed,接着看一下proceed方法

//RealInterceptorChain
public Response proceed(Request request, StreamAllocation streamAllocation, HttpCodec httpCodec,
RealConnection connection) throws IOException {

if (index >= interceptors.size()) throw new AssertionError();
calls++;
// Call the next interceptor in the chain.
RealInterceptorChain next = new RealInterceptorChain(
interceptors, streamAllocation, httpCodec, connection, index + 1, request);
Interceptor interceptor = interceptors.get(index);
Response response = interceptor.intercept(next);

return response;
}

重点看一下Call the next interceptor in the chain 下面几行代码,他把当前的interceptor.intercept()时,传入的是下一个interceptor的包装类,RealInterceptorChain 这样就实现了,链式递归调用了,直到最后一个response返回,才会依次返回到第一个interceptor。

可以用如下图大致描述

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

讲了那么多相关的知识点,我们来回到正题,上述推荐小工具的实现步骤介绍

抓包工具实现主要步骤介绍

添加一个抓包入口

在Manifest中注册即可,如下


自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

最后

代码真的是重质不重量,质量高的代码,是当前代码界提倡的,当然写出高质量的代码肯定需要一个相当高的专业素养,这需要在日常的代码书写中逐渐去吸收掌握,谁不是每天都在学习呀,目的还不是为了一个,为实现某个功能写出高质量的代码。

所以,长征路还长,大家还是好好地做个务实的程序员吧。

最后,小编这里有一系列Android提升学习资料,有兴趣的小伙伴们可以来看下哦~

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!

界提倡的,当然写出高质量的代码肯定需要一个相当高的专业素养,这需要在日常的代码书写中逐渐去吸收掌握,谁不是每天都在学习呀,目的还不是为了一个,为实现某个功能写出高质量的代码。**

所以,长征路还长,大家还是好好地做个务实的程序员吧。

最后,小编这里有一系列Android提升学习资料,有兴趣的小伙伴们可以来看下哦~

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!
  • 29
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值