欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

OKhttp攔截器實現(xiàn)實踐環(huán)節(jié)源碼解析

 更新時間:2023年01月05日 11:35:46   作者:itbird01  
這篇文章主要為大家介紹了OKhttp攔截器實現(xiàn)實踐環(huán)節(jié)源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

正文

本節(jié)我們開始自我實現(xiàn)我們自己okhttp框架中的每個攔截器。

先簡單回顧一下各個攔截器的作用:

  • RetryAndFollowUpInterceptor:重試攔截器

處理重試的一個攔截器,會去處理一些異常,根據(jù)底層返回的響應數(shù)據(jù),先進行一些特殊狀態(tài)碼的判斷,例如:如果底層返回307,則根據(jù)服務端返回的最新location,重新構建新的請求,交由底層攔截器,重新發(fā)起請求。如果底層返回路由異常、某些IO異常,則會continue,重新發(fā)起請求。

  • BridgeInterceptor:基礎的攔截器

給我們平常發(fā)起的請求,添加通用和請求首部信息,做一個簡單的處理,設置一些通用的請求頭,Cookie、Connection、Content-Type、Content-Length,做一些返回的處理,如果返回的數(shù)據(jù)被壓縮了,采用 ZipSource,保存Cookie。

  • CacheInterceptor:緩存攔截器

緩存存儲策略、緩存過期策略、緩存對比策略的具體實現(xiàn)。

  • ConnectInterceptor:連接的攔截器

ConnectInterceptor負責連接復用、建立socket連接,okio與socket輸入輸出流綁定。

  • CallServerInterceptor: 具體與服務器通信,給服務器寫數(shù)據(jù)和讀取數(shù)據(jù);

攔截器的自我實現(xiàn)

好了,接下來,把我們之前寫的框架的代碼,重新梳理一下,新增一下幾個攔截器。 RealCall.java

package com.itbird.okhttpstudy.okhttp;
import android.util.Log;
import com.itbird.okhttpstudy.interceptor.BridgeInterceptor;
import com.itbird.okhttpstudy.interceptor.CacheInterceptor;
import com.itbird.okhttpstudy.interceptor.CallServerInterceptor;
import com.itbird.okhttpstudy.interceptor.ConnectInterceptor;
import com.itbird.okhttpstudy.interceptor.Interceptor;
import com.itbird.okhttpstudy.interceptor.RetryAndFollowUpInterceptor;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
 * Created by itbird on 2022/11/21
 */
public class RealCall implements Call {
    private Request request;
    private OkhttpClient okhttpClient;
    public RealCall(Request request, OkhttpClient okhttpClient) {
        this.request = request;
        this.okhttpClient = okhttpClient;
    }
    @Override
    public void enqueue(Callback callback) {
        okhttpClient.dispatcher().enqueue(new AsyncCall(callback));
    }
    @Override
    public Response execute() {
        return getResponseWithInterceptorChain();
    }
    @Override
    public Request request() {
        return request;
    }
    private Response getResponseWithInterceptorChain() {
        List<Interceptor> interceptors = new ArrayList<Interceptor>();
        interceptors.add(new BridgeInterceptor());// 基礎
        interceptors.add(new CacheInterceptor());// 緩存
        interceptors.add(new ConnectInterceptor());// 建立連接
        interceptors.add(new CallServerInterceptor());// 寫數(shù)據(jù)
        interceptors.add(new RetryAndFollowUpInterceptor());// 重試
        Interceptor.Chain chain = new RealInterceptorChain(this, interceptors, request);
        try {
            return chain.proceed(request);
        } catch (IOException e) {
            //處理過程被中斷時,通過錯誤碼返回
            return null;
        }
    }
    class AsyncCall extends NamedRunnable {
        private Callback callback;
        public AsyncCall(Callback callback) {
            this.callback = callback;
        }
        @Override
        public void execute() {
            Log.d(Constants.TAG, "AsyncCall execute");
            //這里有問題的
            Response response = getResponseWithInterceptorChain();
            if (callback != null) {
                try {
                    callback.onResponse(RealCall.this, response);
                } catch (IOException e) {
                }
            }
        }
    }
}

接下來還是老辦法,按照AS提示,新建這些類。

RetryAndFollowUpInterceptor

package com.itbird.okhttpstudy.interceptor;
import android.util.Log;
import com.itbird.okhttpstudy.okhttp.Constants;
import com.itbird.okhttpstudy.okhttp.Request;
import com.itbird.okhttpstudy.okhttp.Response;
import java.io.IOException;
/**
 * Created by itbird on 2022/11/24
 */
public class RetryAndFollowUpInterceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {
        Log.d(Constants.TAG, "RetryAndFollowUpInterceptor");
        Request request = chain.request();
        //okhttp表現(xiàn)為,此處,去根據(jù)底層拋出的異常,決定是否為關鍵錯誤異常,如果不是,則while true循環(huán),去執(zhí)行重試請求
        return chain.proceed(request);
    }
}

BridgeInterceptor

package com.itbird.okhttpstudy.interceptor;
import android.util.Log;
import com.itbird.okhttpstudy.okhttp.Constants;
import com.itbird.okhttpstudy.okhttp.Request;
import com.itbird.okhttpstudy.okhttp.RequsetBody;
import com.itbird.okhttpstudy.okhttp.Response;
import java.io.IOException;
/**
 * Created by itbird on 2022/11/24
 */
public class BridgeInterceptor implements Interceptor {
    public BridgeInterceptor() {
    }
    @Override
    public Response intercept(Chain chain) throws IOException {
        Log.d(Constants.TAG, "BridgeInterceptor");
        Request request = chain.request();
        // 添加一些請求頭
//        request.addParam("Connection", "keep-alive");
        // 做一些其他處理
        if (request.requsetBody() != null) {
            RequsetBody requestBody = request.requsetBody();
            request.addParam("Content-Type", requestBody.getContentType());
            request.addParam("Content-Length", Long.toString(requestBody.getContentLength()));
        }
        //GZIP數(shù)據(jù)流轉換
        return chain.proceed(request);
    }
}

CacheInterceptor

package com.itbird.okhttpstudy.interceptor;
import android.util.Log;
import com.itbird.okhttpstudy.okhttp.CacheControl;
import com.itbird.okhttpstudy.okhttp.Constants;
import com.itbird.okhttpstudy.okhttp.Request;
import com.itbird.okhttpstudy.okhttp.Response;
import java.io.IOException;
/**
 * Created by itbird on 2022/11/24
 */
public class CacheInterceptor implements Interceptor {
    public CacheInterceptor() {
    }
    @Override
    public Response intercept(Chain chain) throws IOException {
        Log.d(Constants.TAG, "CacheInterceptor");
        Request request = chain.request();
        if (request.cache() == CacheControl.FORCE_CACHE) {
            //本地緩存有沒有,緩存過期了沒有,緩存對比服務器返回307
        }
        return chain.proceed(request);
    }
}

ConnectInterceptor

package com.itbird.okhttpstudy.interceptor;
import android.util.Log;
import com.itbird.okhttpstudy.okhttp.Constants;
import com.itbird.okhttpstudy.okhttp.Request;
import com.itbird.okhttpstudy.okhttp.Response;
import java.io.IOException;
/**
 * Created by itbird on 2022/11/24
 */
public class ConnectInterceptor implements Interceptor {
    public ConnectInterceptor() {
    }
    @Override
    public Response intercept(Chain chain) throws IOException {
        Log.d(Constants.TAG, "ConnectInterceptor");
        Request request = chain.request();
        //表現(xiàn)為okhttp的話,這里就是socket簡歷連接,并且將socket輸入輸出流與okio綁定在一起
        return chain.proceed(request);
    }
}

CallServerInterceptor

package com.itbird.okhttpstudy.interceptor;
import android.util.Log;
import com.itbird.okhttpstudy.okhttp.Constants;
import com.itbird.okhttpstudy.okhttp.Request;
import com.itbird.okhttpstudy.okhttp.Response;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
/**
 * Created by itbird on 2022/11/24
 */
public class CallServerInterceptor implements Interceptor {
    public CallServerInterceptor() {
    }
    @Override
    public Response intercept(Chain chain) throws IOException {
        Log.d(Constants.TAG, "CallServerInterceptor");
        Request request = chain.request();
        try {
            //獲取連接請求
            URL url = new URL(request.url());
            HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
            //設置連接超時
            httpURLConnection.setConnectTimeout(3000);
            //設置方法
            httpURLConnection.setRequestMethod(request.method());
            if (request.requsetBody() != null) {
                httpURLConnection.setRequestProperty("Content-Type", request.requsetBody().getContentType());
                httpURLConnection.setRequestProperty("Content-Length", String.valueOf(request.requsetBody().getContentLength()));
                Log.d(Constants.TAG, httpURLConnection.getRequestProperty("Content-Length"));
                Log.d(Constants.TAG, httpURLConnection.getRequestProperty("Content-Type"));
            }
            //開始連接
            httpURLConnection.connect();
            //插入,如果requsetbody不為空,則繼續(xù)寫入內容
            if (request.requsetBody() != null) {
                request.requsetBody().writeBodyData(httpURLConnection.getOutputStream());
            }
            //判斷返回的狀態(tài)碼
            if (httpURLConnection.getResponseCode() == 200) {
                //獲取返回的數(shù)據(jù)
                InputStream inputStream = httpURLConnection.getInputStream();
                //將返回的數(shù)據(jù),封裝為response
                Response response = new Response(inputStream);
                return response;
            }
        } catch (MalformedURLException e) {
            throw e;
        } catch (IOException e) {
            throw e;
        }
        return null;
    }
}

運行一下

題外話

說到責任鏈模式,這里有一個題外話,我們之前分析view事件源碼的時候,也看到過,view 事件源碼,也是責任鏈機制,它是通過每層返回true、false來決定是否攔截。

大家想一下,和okhttp這里的責任鏈有啥不同的?我們上面查看okhttp源碼的時候知道,它并不是通過每層返回true or false來決定是否攔截的,而是根據(jù)每層返回的response 以及 是否拋出異常來決定是否攔截。

以上就是OKhttp攔截器實現(xiàn)實踐環(huán)節(jié)源碼解析的詳細內容,更多關于OKhttp 攔截器實現(xiàn)的資料請關注腳本之家其它相關文章!

相關文章

最新評論