前言
OkHttp系列文章
OkHttp系列文章(一) - Java网络编程基础
OkHttp系列文章(二) - Http与Https
OkHttp系列文章(三) - OkHttp
OkHttp系列文章(四) - OkHttp拦截器原理
OkHttp系列文章(五) - OkHttp的5个拦截器作用
OkHttp系列文章(六) - OkHttp的5个拦截器图解分析
OkHttp系列文章(七) - 文件更新下载
1. 同步与异步
二者与线程没什么关系,比如打电话:
同步:打电话 -> 处理(没挂断) -> 反馈
异步:打电话 -> 处理(挂断了) -> 打回来,可能有接口回调
2. 自己如果写一个网络框架如何去写?
1>:网络是耗时的,就需要开线程,new Thread()?,不可能,如果有100个接口,你就需要创建100个线程,这个不现实,就需要线程池;
2>:处理网络要基于,HttpUrlConnection 或者熟悉输入、输出流+socket;
3>:网络请求头信息的处理,比如304、307等;
4>:缓存的处理、文件格式上传的方式(表单提交、拼接格式);
5>: 路由的一些操作,Http2.0的复用等等
3. OkHttp大致内容:
1>:Okio:原生java的 io + 自定义封装,通俗的讲,其实就是对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. 构建一个请求 ,url,端口,请求头的一些参数,表单提交(contentType,contentLength)
// 把所有数据存储到 Request中
Request request = new Request.Builder()
.url("http://www.baidu.com").build();
// 2. 把 Request 封装转成一个 RealCall
Call call = okHttpClient.newCall(request);
// 3. enqueue 队列处理 执行
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();
这句代码意思就是:构建一个请求,把所有数据存储到 Request中,比如有url、端口、请求头的一席参数、表单提交(contentType、contentLength)等;
2>: Call call = okHttpClient.newCall(request);
这句代码意思就是:把Request 封装成一个 RealCall
3>: call.enqueue(new Callback():
这句代码是核心代码,这个是 方法是RealCall中的 enqueue()方法;
AsyncCall 是 RealCall的内部类,给了 OkHttp的 Dispatcher,下边是 Dispatcher中的 enqueue()方法:
synchronized void enqueue(AsyncCall call) {
// 判断当前正在执行的 任务数量,最大是 64,正在执行的 任务中的 host,最大是 5
if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
// 加入到正在执行
runningAsyncCalls.add(call);
// 加入到线程池中执行
executorService().execute(call);
} else {
// 加入准备执行的集合,等待执行
readyAsyncCalls.add(call);
}
}
executorService().execute(call);这个方法最终去了哪里?
最终来到了 AsyncCall.execute()方法,执行getResponseWithInterceptorChain 返回 Response