OkHttp 的拦截器,那一块的代码很多,也比较复杂,在 debug 的时候好多个类来回跳,看的很懵,其实把整个框架拿出来,简化一些之后再看,就清晰多了。下面就是一个简化后的,为了更容易理解,对应的类名还是用了 OkHttp 中的类名,返回的值直接用 String。
-
首先是定义一个接口
public interface Interceptor { // 拦截 String intercept(Chain chain); interface Chain // 分发 String proceed(String request); } }
-
创建 5 个 interceptor 类分别是:RetryAndFollowUpInterceptor、BridgeInterceptor、CacheInterceptor、ConnectInterceptor、CallServerInterceptor ,实现 Interceptor 接口,重写 intercept(Chain chain) 方法,在这个方法里调用 chain.proceed() 方法
@Override public String intercept(Chain chain) { chain.proceed("CacheInterceptor"); System.out.println("CacheInterceptor"); return "CacheInterceptor"; }
-
接下来创建一个类 RealInterceptorChain 实现 Chain 接口,重写 proceed() 方法,在该方法里遍历 interceptor,并调用 interceptor.intercept() 方法
RealInterceptorChain next = new RealInterceptorChain(index + 1,interceptors); Interceptor interceptor = interceptors.get(index); System.out.println("遍历 interceptor 的值:第" + (index + 1) + "个 interceptor:"); System.out.println("RealInterceptor:" + interceptor.getClass().getName()); // 在 interceptor 的 intercept 方法里需要用到 Chain 对象,所以在每次取出 interceptor 对象的时候,也要重新创建一个 Chain 对象 String intercept = interceptor.intercept(next);
注:实现 Chain 的类只有 RealInterceptorChain 这一个类。
-
添加 interceptors,然后开始迭代
List<Interceptor> interceptors = new ArrayList<>(); interceptors.add(new RetryAndFollowUpInterceptor()); interceptors.add(new BridgeInterceptor()); interceptors.add(new CacheInterceptor()); interceptors.add(new ConnectInterceptor()); interceptors.add(new CallServerInterceptor()); RealInterceptorChain chain = new RealInterceptorChain(0,interceptors); String real_call = chain.proceed("real call");
注:chain.proceed() 迭代的开始。
-
当执行完chain.proceed() 方法后就会进入到它的实现类中去,也就是 RealInterceptorChain 类中的 proceed() 方法,也就是第三步中的代码里,在这个方法里核心的一句: interceptor.intercept(next),执行这一句就会进入到 interceptor 对应的实现类中去,这时的实现类是 RetryAndFollowUpInterceptor,也就是它的 intercept() 方法中去,也就是第二步中的代码,在这个方法最核心的一句 :chain.proceed(“CacheInterceptor”),执行这一句,又会回到第三步,创建一个新的 RealInterceptorChain、取出下一个 interceptor,开始又一轮的迭代。
-
当执行到最后一个 interceptor 时,这里对应的是 CallServerInterceptor,在它的 intercept 方法中没有再执行 chain.proceed() 方法,遍历结束,继续后面的操作。
@Override public String intercept(Chain chain) { System.out.println("interceptors 中最后一个 interceptor, intercept 中不再执行 chain,遍历结束,开始返回值"); System.out.println("CallServerInterceptor"); return "返回的值:CallServerInterceptor"; }
-
结束遍历之后,开始返回数据,返回的时候从最后一个 interceptor 开始返回,依次返回到第一个,最后返回到最初调用的地方。