白話Okhttp攔截器調用過程

攔截器調用順序一般為順序調用,將上一個攔截器的返回作為下一個攔截器的輸入,直到所有攔截器執(zhí)行完畢,返回最終結果。這里通過for循環(huán)先模擬一個簡單的攔截器調用過程,再模擬okhttp攔截器工作過程

簡單順序攔截器調用

模擬屏蔽詞:

 public static Response execute() {
        //模擬所有攔截器
        List<Interceptor> mInterceptorList = new ArrayList<Interceptor>() {{
            add(new FatherInterceptor());
            add(new GrandpaInterceptor());
        }};
        Chain chain = new RealInterceptor("我是你爸爸,我是你爺爺");
        Response response = null;
        for (Interceptor interceptor : mInterceptorList) {
            response = interceptor.intercept(chain);
            chain = new RealInterceptor(response.result);
        }
        return response;
    }


    public static class RealInterceptor implements Chain {

        private String params;

        public RealInterceptor(String params) {
            this.params = params;
        }

        @Override
        public Request request() {
            return new Request(params);
        }
    }

    public static class FatherInterceptor implements Interceptor {

        @Override
        public Response intercept(Chain chain) {
            Response response = new Response(chain.request().params.replace("爸爸", "**"));
            return response;
        }
    }

    public static class GrandpaInterceptor implements Interceptor {

        @Override
        public Response intercept(Chain chain) {
            Response response = new Response(chain.request().params.replace("爺爺", "**"));
            return response;
        }
    }

    public static interface Interceptor {

        Response intercept(Chain chain) throws RuntimeException;

        interface Chain {

            Request request();

        }
    }

    public static class Response {

        public Response(String result) {
            this.result = result;
        }

        public String result;
    }

    public static class Request {

        public Request(String params) {
            this.params = params;
        }

        public String params;
    }

當調用execute()將得到以下reponse:

image.png

模擬OKhttp模擬器攔截調用

okhttp攔截器調用核心步驟

  • 構建Request,在當前調用鏈Chain中獲取當前要執(zhí)行的攔截器Interceptor
  • 創(chuàng)建下一個調用鏈RealInterceptor,將該調用鏈作為當前攔截器的參數(shù)Chain
  • 在當前攔截器中執(zhí)行攔截動作intercept(Chain chain),并調用下一個攔截器的proceed
  • 在下一個調用鏈的proceed(Request request)判斷是否所有攔截器執(zhí)行完畢,如果沒有執(zhí)行完畢重復繼續(xù)以上步驟,如果全部執(zhí)行完畢拋出特定Exception,攔截器中捕捉該異常并構建最終返回結果。
 public static Response execute() {
        Chain chain = new RealInterceptor(0, new Request("request params"));
        Response response = chain.proceed(chain.request());
        return response;
    }


    public static class RealInterceptor implements Interceptor.Chain {
        //請求攔截器位置
        int index = 0;
        //請求體
        Request mRequest;

        public RealInterceptor(int count, Request request) {
            this.index = count;
            this.mRequest = request;
        }
        //模擬所有攔截器
        private List<Interceptor> mInterceptorList = new ArrayList<Interceptor>() {{
            add(new BridgeInterceptor());
            add(new CacheInterceptor());
            add(new ConnectionInterceptor());
            add(new ServerInterceptor());
        }};

        @Override
        public Request request() {
            return mRequest;
        }

        @Override
        public Response proceed(Request request) {
            if (index >= mInterceptorList.size()) {
                //所有攔截器執(zhí)行結束,拋出特定異常
                throw new RuntimeException("interceptors execute finish");
            }
            //執(zhí)行當前下標的攔截器
            Interceptor interceptor = mInterceptorList.get(index);
            //創(chuàng)建下一個調用鏈
            RealInterceptor next = new RealInterceptor(index + 1, request);
            //獲取調用鏈結果
            Response response = interceptor.intercept(next);
            return response;
        }
    }

    public static class BridgeInterceptor implements Interceptor {

        @Override
        public Response intercept(Chain chain) {
            chain.request().params += "-" + "BridgeInterceptor";
            Response response = null;
            try {
                response = chain.proceed(chain.request());
            } catch (Exception e){

            }
            if (response == null) {
                //執(zhí)行結束構建最后的Response
                return new Response(chain.request().params);
            }
            return response;
        }
    }

    public static class CacheInterceptor implements Interceptor {

        @Override
        public Response intercept(Chain chain) {
            chain.request().params += "-" + "CacheInterceptor";
            Response response = null;
            try {
                response = chain.proceed(chain.request());
            } catch (Exception e){

            }
            if (response == null) {
                //執(zhí)行結束構建最后的Response
                return new Response(chain.request().params);
            }
            return response;
        }
    }

    public static class ConnectionInterceptor implements Interceptor {

        @Override
        public Response intercept(Chain chain) {
            chain.request().params += "-" + "ConnectionInterceptor";
            Response response = null;
            try {
                response = chain.proceed(chain.request());
            } catch (Exception e){

            }
            if (response == null) {
                //執(zhí)行結束構建最后的Response
                return new Response(chain.request().params);
            }
            return response;
        }
    }
    public static class ServerInterceptor implements Interceptor {

        @Override
        public Response intercept(Chain chain) {
            chain.request().params += "-" + "Reponse";
            Response response = null;
            try {
                response = chain.proceed(chain.request());
            } catch (Exception e){

            }
            if (response == null) {
                //執(zhí)行結束構建最后的Response
                return new Response(chain.request().params);
            }
            return response;
        }
    }
    public static interface Interceptor {

        Response intercept(Chain chain) throws RuntimeException;

        interface Chain {

            Request request();

            Response proceed(Request request) throws RuntimeException;
        }
    }

    public static class Response {

        public Response(String result) {
            this.result = result;
        }

        public String result;
    }

    public static class Request {

        public Request(String params) {
            this.params = params;
        }

        public String params;
    }

當調用execute()將得到以下reponse:

image.png

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容