OkHttp 的攔截器些己,那一塊的代碼很多,也比較復(fù)雜嘿般,在 debug 的時候好多個類來回跳段标,看的很懵,其實(shí)把整個框架拿出來炉奴,簡化一些之后再看逼庞,就清晰多了。下面就是一個簡化后的瞻赶,為了更容易理解往堡,對應(yīng)的類名還是用了 OkHttp 中的類名,返回的值直接用 String共耍。
-
首先是定義一個接口
public interface Interceptor { // 攔截 String intercept(Chain chain); interface Chain // 分發(fā) String proceed(String request); } }
-
創(chuàng)建 5 個 interceptor 類分別是:RetryAndFollowUpInterceptor、BridgeInterceptor吨瞎、CacheInterceptor痹兜、ConnectInterceptor、CallServerInterceptor 颤诀,實(shí)現(xiàn) Interceptor 接口字旭,重寫 intercept(Chain chain) 方法,在這個方法里調(diào)用 chain.proceed() 方法
@Override public String intercept(Chain chain) { chain.proceed("CacheInterceptor"); System.out.println("CacheInterceptor"); return "CacheInterceptor"; }
-
接下來創(chuàng)建一個類 RealInterceptorChain 實(shí)現(xiàn) Chain 接口崖叫,重寫 proceed() 方法遗淳,在該方法里遍歷 interceptor,并調(diào)用 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 對象的時候屈暗,也要重新創(chuàng)建一個 Chain 對象 String intercept = interceptor.intercept(next);
注:實(shí)現(xiàn) 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() 迭代的開始养叛。
當(dāng)執(zhí)行完chain.proceed() 方法后就會進(jìn)入到它的實(shí)現(xiàn)類中去,也就是 RealInterceptorChain 類中的 proceed() 方法宰翅,也就是第三步中的代碼里弃甥,在這個方法里核心的一句: interceptor.intercept(next),執(zhí)行這一句就會進(jìn)入到 interceptor 對應(yīng)的實(shí)現(xiàn)類中去汁讼,這時的實(shí)現(xiàn)類是 RetryAndFollowUpInterceptor淆攻,也就是它的 intercept() 方法中去阔墩,也就是第二步中的代碼,在這個方法最核心的一句 :chain.proceed("CacheInterceptor")瓶珊,執(zhí)行這一句啸箫,又會回到第三步,創(chuàng)建一個新的 RealInterceptorChain艰毒、取出下一個 interceptor筐高,開始又一輪的迭代。
-
當(dāng)執(zhí)行到最后一個 interceptor 時丑瞧,這里對應(yīng)的是 CallServerInterceptor柑土,在它的 intercept 方法中沒有再執(zhí)行 chain.proceed() 方法,遍歷結(jié)束绊汹,繼續(xù)后面的操作稽屏。
@Override public String intercept(Chain chain) { System.out.println("interceptors 中最后一個 interceptor, intercept 中不再執(zhí)行 chain,遍歷結(jié)束西乖,開始返回值"); System.out.println("CallServerInterceptor"); return "返回的值:CallServerInterceptor"; }
結(jié)束遍歷之后狐榔,開始返回數(shù)據(jù),返回的時候從最后一個 interceptor 開始返回获雕,依次返回到第一個薄腻,最后返回到最初調(diào)用的地方。