OkHttp 源碼分析

基本使用

  //1. 創建OkHttpClient實例
  OkHttpClient client = new OkHttpClient
                            	.Builder()
                            	.cache(new Cache(new File("cache"), 24 * 1024 * 1024))
                            	.build();
  //2. 創建Request實例                        
	Request request = new Request.Builder().url("http://www.baidu.com").build();
  //3. 創建Call實例  
	Call call = client.newCall(request);
  //4.執行同步請求
	try {
		Response response = call.execute();
		response.close();
	} catch (IOException e) {
		e.printStackTrace();
	}

	//5.執行異步請求
	call.enqueue(new Callback() {

		@Override
		public void onFailure(Call call, IOException e) {
			System.out.println("連接失敗");
		}

		@Override
		public void onResponse(Call call, Response response) throws IOException {
			//請求處理,輸出結果
			System.out.println(response.body());
		}
});

源碼分析

** 創建OkHttpClient實例 **

//建造者設計模式 創建OkHttpClient實例
public OkHttpClient build() {
       return new OkHttpClient(this);
}

** 創建Request請求實體 **

public final class Request {
    final HttpUrl url;
    final String method;
    final Headers headers;
    @Nullable
    final RequestBody body;
    final Object tag;
    private volatile CacheControl cacheControl;
    ...
}
//通過建造者設計模式 創建Request請求實體
Request request = new Request.Builder().url("http://www.baidu.com").build();

** 接下來看看Call的獲取 **

Call call = client.newCall(request);

public Call newCall(Request request) {
    return RealCall.newRealCall(this, request, false);
}

//創建一個RealCall實例
static RealCall newRealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
		RealCall call = new RealCall(client, originalRequest, forWebSocket);
		call.eventListener = client.eventListenerFactory().create(call);
		return call;
}

** 執行同步請求execute **

public Response execute() throws IOException {
	synchronized(this) {
		if(this.executed) {
			throw new IllegalStateException("Already Executed");
		}

		this.executed = true;
	}

	this.captureCallStackTrace();
	this.eventListener.callStart(this);

	Response var2;
	try {
    //分發器執行 其實就是直接將請求放到運行請求隊列裏面去 等會下面有分析這個Dispatcher
		this.client.dispatcher().executed(this);
    //責任鏈方式 執行鏈式操作 核心 裏面分析
		Response result = this.getResponseWithInterceptorChain();
		if(result == null) {
			throw new IOException("Canceled");
		}

		var2 = result;
	} catch (IOException var7) {
		this.eventListener.callFailed(this, var7);
		throw var7;
	}
	finally {
		this.client.dispatcher().finished(this);
	}

	return var2;
}


** getResponseWithInterceptorChain 方法裏面的核心內容 **

Response getResponseWithInterceptorChain() throws IOException {
  //創建一個Interceptor集合列表
	List<Interceptor> interceptors = new ArrayList();
  //加入我們客戶端設置的攔截器
	interceptors.addAll(this.client.interceptors());
  //加入retryAndFollowUpInterceptor 負責失敗重試以及重定向
	interceptors.add(this.retryAndFollowUpInterceptor);
  //加入BridgeInterceptor 負責把用戶構造的請求轉換爲發送到服務器的請求、把服務器返回的響應轉換爲用戶友好的響應的 。
	interceptors.add(new BridgeInterceptor(this.client.cookieJar()));
  //加入CacheInterceptor 緩存
	interceptors.add(new CacheInterceptor(this.client.internalCache()));
  //加入ConnectInterceptor 建立連接
	interceptors.add(new ConnectInterceptor(this.client));
	if(!this.forWebSocket) {
		interceptors.addAll(this.client.networkInterceptors());
	}
  //CallServerInterceptor 發送和接收數據
	interceptors.add(new CallServerInterceptor(this.forWebSocket));
  //RealInterceptorChain 總得鏈式處理管理器
	Chain chain = new RealInterceptorChain(interceptors, (StreamAllocation)null, (HttpCodec)null, (RealConnection)null, 0, this.originalRequest, this, this.eventListener, this.client.connectTimeoutMillis(), this.client.readTimeoutMillis(), this.client.writeTimeoutMillis());
  //執行同步請求execute 之後 走完鏈式的執行攔截器後,返回的最終的結果
	return chain.proceed(this.originalRequest);
}

** 異步執行 enqueue

//RealCall#enqueue
public void enqueue(Callback responseCallback) {
        synchronized(this) {
            if(this.executed) {
                throw new IllegalStateException("Already Executed");
            }

            this.executed = true;
        }

        this.captureCallStackTrace();
        this.eventListener.callStart(this);
        //調用Dispatcher 裏面的 enqueue方法
        this.client.dispatcher().enqueue(new RealCall.AsyncCall(responseCallback));
    }

    synchronized void enqueue(AsyncCall call) {
           if(this.runningAsyncCalls.size() < this.maxRequests && this.runningCallsForHost(call) < this.maxRequestsPerHost) {
              //將AsyncCall 放入runningAsyncCallsiebiao裏面
               this.runningAsyncCalls.add(call);
               //調用線程池去執行異步請求Call AsyncCall#execute方法
               this.executorService().execute(call);
           } else {
               this.readyAsyncCalls.add(call);
           }

       }

** AsyncCall#execute方法 **

//異步Call
final class AsyncCall extends NamedRunnable {
	private final Callback responseCallback;

	AsyncCall(Callback responseCallback) {
		super("OkHttp %s", new Object[] {RealCall.this.redactedUrl()});
		this.responseCallback = responseCallback;
	}

	String host() {
		return RealCall.this.originalRequest.url().host();
	}

	Request request() {
		return RealCall.this.originalRequest;
	}

	RealCall get() {
		return RealCall.this;
	}

	protected void execute() {
		boolean signalledCallback = false;

		try {
      //還是責任鏈裏面的鏈式請求操作
			Response response = RealCall.this.getResponseWithInterceptorChain();
      //通過響應的結果進行不同的回調操作
			if(RealCall.this.retryAndFollowUpInterceptor.isCanceled()) {
				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 {
				RealCall.this.eventListener.callFailed(RealCall.this, var6);
				this.responseCallback.onFailure(RealCall.this, var6);
			}
		}
		finally {
			RealCall.this.client.dispatcher().finished(this);
		}

	}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章