天天看點

Android網絡通信架構-OKHttp源碼解析

OkHttp

作為現代的Http請求用戶端,可以在java或者android使用,有以下特點

1、支援SPDY

2、連接配接池,實作Http1.1長連接配接和http2.0多路複用

3、攔截器,内部預置攔截器和自定義攔截器支援,可以往HTTP請求時插入邏輯和職責

4、支援GZI和HTTP緩存

使用方法:

OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder().url("http://www.baidu.com").get().build(); //建造者設計模式

Call call = client.newCall(request);

call.enqueue(new Callback() { @Override

public void onFailure(Call call, IOException e) {

Log.e("initGetNetData","onFailure"+e); } @Override

public void onResponse(Call call, Response response) throws IOException {

Log.e("initGetNetData","onResponse"+response.body().toString());

} });

源碼分析:

public Builder() {
    this.dispatcher = new Dispatcher();
    this.protocols = OkHttpClient.DEFAULT_PROTOCOLS;
    this.connectionSpecs = OkHttpClient.DEFAULT_CONNECTION_SPECS;
    this.proxySelector = ProxySelector.getDefault();
    this.cookieJar = CookieJar.NO_COOKIES;
    this.socketFactory = SocketFactory.getDefault();
    this.hostnameVerifier = OkHostnameVerifier.INSTANCE;
    this.certificatePinner = CertificatePinner.DEFAULT;
    this.proxyAuthenticator = Authenticator.NONE;
    this.authenticator = Authenticator.NONE;
    this.connectionPool = new ConnectionPool();
    this.dns = Dns.SYSTEM;
    this.followSslRedirects = true;
    this.followRedirects = true;
    this.retryOnConnectionFailure = true;
    this.connectTimeout = 10000;
    this.readTimeout = 10000;
    this.writeTimeout = 10000;
}

Builder(OkHttpClient okHttpClient) {
    this.dispatcher = okHttpClient.dispatcher;
    this.proxy = okHttpClient.proxy;
    this.protocols = okHttpClient.protocols;
    this.connectionSpecs = okHttpClient.connectionSpecs;
    this.interceptors.addAll(okHttpClient.interceptors);
    this.networkInterceptors.addAll(okHttpClient.networkInterceptors);
    this.proxySelector = okHttpClient.proxySelector;
    this.cookieJar = okHttpClient.cookieJar;
    this.internalCache = okHttpClient.internalCache;
    this.cache = okHttpClient.cache;
    this.socketFactory = okHttpClient.socketFactory;
    this.sslSocketFactory = okHttpClient.sslSocketFactory;
    this.certificateChainCleaner = okHttpClient.certificateChainCleaner;
    this.hostnameVerifier = okHttpClient.hostnameVerifier;
    this.certificatePinner = okHttpClient.certificatePinner;
    this.proxyAuthenticator = okHttpClient.proxyAuthenticator;
    this.authenticator = okHttpClient.authenticator;
    this.connectionPool = okHttpClient.connectionPool;
    this.dns = okHttpClient.dns;
    this.followSslRedirects = okHttpClient.followSslRedirects;
    this.followRedirects = okHttpClient.followRedirects;
    this.retryOnConnectionFailure = okHttpClient.retryOnConnectionFailure;
    this.connectTimeout = okHttpClient.connectTimeout;
    this.readTimeout = okHttpClient.readTimeout;
    this.writeTimeout = okHttpClient.writeTimeout;
}
           

public Call newCall(Request request)

{ return new RealCall(this, request); }

//dispatch()執行了這個方法,它将匿名内部類傳遞到AsyncCall這個Runnable中
void enqueue(Callback responseCallback, boolean forWebSocket) {
    synchronized(this) {
        if (this.executed) {
            throw new IllegalStateException("Already Executed");
        }

        this.executed = true;
    }

    this.client.dispatcher().enqueue(new RealCall.AsyncCall(responseCallback, forWebSocket));
}
           

//任務排程器把建立好的線程池傳入到AsyncCall裡面

AsyncCall call = (AsyncCall)i.next();
if (this.runningCallsForHost(call) < this.maxRequestsPerHost) {
    i.remove();
    this.runningAsyncCalls.add(call);
    this.executorService().execute(call);
}
           
Android網絡通信架構-OKHttp源碼解析
//核心代碼
protected void execute() {
        boolean signalledCallback = false;

        try {
            Response response = RealCall.this.getResponseWithInterceptorChain(this.forWebSocket);
            if (RealCall.this.canceled) {
                signalledCallback = true;
                this.responseCallback.onFailure(RealCall.this, new IOException("Canceled"));
            } else {
                signalledCallback = true;
                this.responseCallback.onResponse(RealCall.this, response);
            }
        } catch (IOException var6) {
            if (signalledCallback) {
                Platform.get().log(4, "Callback failure for " + RealCall.this.toLoggableString(), var6);
            } else {
                this.responseCallback.onFailure(RealCall.this, var6);
            }
        } finally {
            RealCall.this.client.dispatcher().finished(this);
        }

    }
           

CallServerInterceptor源碼解析

繼續閱讀