OkHttp网络框架
同步Git请求
步骤:1.创建OkHttpClient.class类(Http请求的客户端类)
方法:①默认: new一个对象
②Builder的内部类(dispatcher:接收同步或者异步的请求队列根据所要的条件进行相应的同步和异步的分发)
2.创建Request()(请求报文的一些信息):包含常用的url地址以及一些方法,设置请求头。
3.创建Call对象:连接Request和Response的桥梁,是实际的okHttp请求。
分水岭
Call call = client.newCall(request);//call只是一个接口。
call.execute();//同步发送请求
call.enqueue();//异步发送请求
注: 发送同步请求之后就会阻塞,直到响应了之后才会停止。异步请求不会阻塞当前线程,他会再次开启一个工作线程来处理数据。
RealCall是Call的具体实现类。
getResponseWithInterceptorChain():构建了一个拦截器链,通过依次执行拦截器链中的不同作用的拦截器来获取服务器中的数据返回。
异步Git请求
步骤:
1.创建client()对象
2.将request封装成一个Call对象
3.调用call.enqueue()方法。
call.enqueue(new Callback(){
@Override
public void onFailure(Call call,IOEception e){
System.out.println("Fail");//失败
}
@Override
public void onResponse(Call call,Response response)throws IOException{
System.out.println(response.body().string());//成功处理数据
}
});
Dispatcher()分发期类,进行异步的请求是就绪还是执行的选择
Okhttp框架同步请求流程和源码分析
1.创建了client()客户端类
public Builder() {
dispatcher = new Dispatcher();//事件分发器类,同步请求是将请求放在队列里
...
connectionPool = new ConnectionPool();
/*连接池:用来存放客户端和服务端之间连接的connection。
作用:①在url相同的情况下可以复用
②对于实现了那些网络连接保持打开状态,哪些用于自用的策略设置。
*/
...
}
Builder()作用:封装okhttp.client,初始化需要的参数,传递Builder()到okhttp构造方法里初始化。
2.构建了携带请求信息的Request对象
Request也是Builder()方式创建的。
public Builder() {
this.method = "GET";//指定请求方式,默认方法为"GET"
this.headers = new Headers.Builder();//保存头部信息
}
public Request build() {
if (url == null) throw new IllegalStateException("url == null");
return new Request(this);
}
将配置好的参数赋值给Request对象
private Request(Builder builder) {
this.url = builder.url;
this.method = builder.method;
this.headers = builder.headers.build();
this.body = builder.body;
this.tag = builder.tag != null ? builder.tag : this;
}
3.通过Call进行同步请求
通过client和request对象构建出实际进行请求的Call对象。
Call call=client.newCall(request);
通过源码我们可以发现,Call实际是一个接口,实际操作都在RealCall中进行操作。
/**
* Prepares the {@code request} to be executed at some point in the future.
*/
public Call newCall(Request request) {
return new RealCall(this, request);
}
protected RealCall(OkHttpClient client, Request originalRequest) {
this.client = client;
this.originalRequest = originalRequest;
this.retryAndFollowUpInterceptor = new RetryAndFollowUpInterceptor(client);
}
RealCall拥有了前两步初始化好的client和Reques对象,同时还赋值了一个重定向拦截器、
注:不管是同步请求还是异步请求都是调用了client.newCall()进行创建,通过创建好的call对像进行相应的操作。
4.通过call.excute()方法完成同步请求操作
由于call是一个接口,所以最后还是要看具体实现类RealCall方法·
public Response execute() throws IOException {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;//同一个Http请求只能执行一次,没有执行过的就会把它设为true,处理过了就会抛出异常。
}
try {
client.dispatcher().executed(this);//只做了一个返回dispatcher对象的操作
Response result = getResponseWithInterceptorChain();//拦截器链
if (result == null) throw new IOException("Canceled");
return result;
} finally {
client.dispatcher().finished(this);//主动去回收它的某些同步请求
}
}
/** Used by {@code Call#execute} to signal it is in-flight. */
synchronized void executed(RealCall call) {
runningSyncCalls.add(call);//同步请求只是通过此方法将其添加到队列之中
}
private <T> void finished(Deque<T> calls, T call, boolean promoteCalls) {
int runningCallsCount;
Runnable idleCallback;
synchronized (this) {
if (!calls.remove(call)) throw new AssertionError("Call wasn't in-flight!");
if (promoteCalls) promoteCalls();//同步的时候promoteCalls是false,异步的是true。
runningCallsCount = runningCallsCount();
/*
计算还在运行的请求总和
总和为0时,表示没有dispatcher分发器类中可运行的请求了,而且CallBack不为空时,就会调用 run()方法
*/
idleCallback = this.idleCallback;
}
diapatcher()只是一个维持Call请求发给他的状态,同时维护了线程池用于执行网络请求,Call请求在执行任务的时候要通过这个diapatcher()分发器类推到执行队列当中进行操作。请求队列也是在dispatcher()中定义的,异步的就绪队列和异步的执行队列也在这定义