前言
OkHttp系列文章
OkHttp系列文章(一) - Java網(wǎng)絡(luò)編程基礎(chǔ)
OkHttp系列文章(二) - Http與Https
OkHttp系列文章(三) - OkHttp
OkHttp系列文章(四) - OkHttp攔截器原理
OkHttp系列文章(五) - OkHttp的5個攔截器作用
OkHttp系列文章(六) - OkHttp的5個攔截器圖解分析
OkHttp系列文章(七) - 文件更新下載
1. 同步與異步
二者與線程沒什么關(guān)系肌稻,比如打電話:
同步:打電話 -> 處理(沒掛斷) -> 反饋
異步:打電話 -> 處理(掛斷了) -> 打回來,可能有接口回調(diào)
2. 自己如果寫一個網(wǎng)絡(luò)框架如何去寫?
1>:網(wǎng)絡(luò)是耗時的,就需要開線程畅铭,new Thread()服傍?,不可能巡雨,如果有100個接口棍辕,你就需要創(chuàng)建100個線程暮现,這個不現(xiàn)實(shí),就需要線程池楚昭;
2>:處理網(wǎng)絡(luò)要基于送矩,HttpUrlConnection 或者熟悉輸入、輸出流+socket哪替;
3>:網(wǎng)絡(luò)請求頭信息的處理,比如304菇怀、307等凭舶;
4>:緩存的處理、文件格式上傳的方式(表單提交爱沟、拼接格式)帅霜;
5>: 路由的一些操作,Http2.0的復(fù)用等等
3. OkHttp大致內(nèi)容:
1>:Okio:原生java的 io + 自定義封裝呼伸,通俗的講身冀,其實(shí)就是對io的封裝。對輸入流括享、輸出流的封裝搂根;
2>:原生的socket連接:
4. OkHttp部分源碼分析
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
OkHttpClient okHttpClient = new OkHttpClient();
// 307 Location:https://www.baidu.com
// 1. 構(gòu)建一個請求 ,url,端口铃辖,請求頭的一些參數(shù)剩愧,表單提交(contentType,contentLength)
// 把所有數(shù)據(jù)存儲到 Request中
Request request = new Request.Builder()
.url("http://www.baidu.com").build();
// 2. 把 Request 封裝轉(zhuǎn)成一個 RealCall
Call call = okHttpClient.newCall(request);
// 3. enqueue 隊列處理 執(zhí)行
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String result = response.body().string();
Log.e("TAG",result);
}
});
}
}
分析上邊源碼可知:
1>:Request request = new Request.Builder().url("http://www.baidu.com").build();
這句代碼意思就是:構(gòu)建一個請求,把所有數(shù)據(jù)存儲到 Request中娇斩,比如有url仁卷、端口、請求頭的一席參數(shù)犬第、表單提交(contentType锦积、contentLength)等;
2>: Call call = okHttpClient.newCall(request);
這句代碼意思就是:把Request 封裝成一個 RealCall
3>: call.enqueue(new Callback():
這句代碼是核心代碼歉嗓,這個是 方法是RealCall中的 enqueue()方法丰介;
AsyncCall 是 RealCall的內(nèi)部類,給了 OkHttp的 Dispatcher,下邊是 Dispatcher中的 enqueue()方法:
synchronized void enqueue(AsyncCall call) {
// 判斷當(dāng)前正在執(zhí)行的 任務(wù)數(shù)量基矮,最大是 64淆储,正在執(zhí)行的 任務(wù)中的 host,最大是 5
if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
// 加入到正在執(zhí)行
runningAsyncCalls.add(call);
// 加入到線程池中執(zhí)行
executorService().execute(call);
} else {
// 加入準(zhǔn)備執(zhí)行的集合家浇,等待執(zhí)行
readyAsyncCalls.add(call);
}
}
executorService().execute(call);這個方法最終去了哪里本砰?
最終來到了 AsyncCall.execute()方法,執(zhí)行g(shù)etResponseWithInterceptorChain 返回 Response