OkHttp Interceptor 的迭代遞迴實現的簡化
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 開始返回,依次返回到第一個,最後返回到最初呼叫的地方。