OkHttp是由Square公司提供的处理网络请求的开源库,有以下特性:
Retrofit也是Square公司产品,是对OkHttp的封装,将网络请求交给OkHttp,自身就可以通过简单的配置就可以进行网络请求了(后面讨论的Retrofit都是2.0版本)
不做具体介绍,可以看官方使用文档:OkHttp、Retrofit
* newCall--实际是调用realCall
protected RealCall(OkHttpClient client, Request originalRequest) {
this.client = client;
this.originalRequest = originalRequest;
this.retryAndFollowUpInterceptor = new RetryAndFollowUpInterceptor(client);
}
* excuate()--先判断这个请求是否执行了,然后通过getResponseWithInterceptorChain()获取响应
@Override
public Response execute() throws IOException {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed"); //(1)
executed = true;
}
try {
client.dispatcher.executed(this);//(2)
Response result = getResponseWithInterceptorChain();//(3)
if (result == null) throw new IOException("Canceled");
return result;
}finally {
client.dispatcher.finished(this);//(4)
}
}
* getResponseWithInterceptorChain()--使用拦截器的责任链获取响应,然后proceed()开始执行链式拦截器
//将拦截器链式加入,通过链式调用
//拦截器的作用:拦截器是OkHttp框架提供的对http的请求和响应进行同意处理的机制
//多个拦截器还可以连接形成一个链再使用,拦截器会按照链式上的顺序依次执行
//拦截器会先对请求进行修改,然后获取响应之后也会对响应进行修改
private Response getResponseWithInterceptorChain() throws IOException {
// Build a full stack of interceptors.
List interceptors = new ArrayList<>();
interceptors.addAll(client.interceptors()); //(1)
interceptors.add(retryAndFollowUpInterceptor); //(2)
interceptors.add(new BridgeInterceptor(client.cookieJar())); //(3)
interceptors.add(new CacheInterceptor(client.internalCache())); //(4)
interceptors.add(new ConnectInterceptor(client)); //(5)
if (!retryAndFollowUpInterceptor.isForWebSocket()) {
interceptors.addAll(client.networkInterceptors()); //(6)
}
interceptors.add(new CallServerInterceptor(
retryAndFollowUpInterceptor.isForWebSocket())); //(7)
Interceptor.Chain chain = new RealInterceptorChain(
interceptors, null, null, null, 0, originalRequest);
return chain.proceed(originalRequest); // <<=========开始链式调用
}
* proceed()--实例化一个RealIterceptorChain对象,在一个存放Interceptor的ArrayList中获取当前的Interceptor,
当前的Interceptor.intercept()方法调用RealIterceptorChain,并传递
public Response proceed(Request request, StreamAllocation streamAllocation, HttpCodec httpCodec,
Connection connection) throws IOException {
if (index >= interceptors.size()) throw new AssertionError();
calls++;
// If we already have a stream, confirm that the incoming request will use it.
//如果我们已经有一个stream。确定即将到来的request会使用它
if (this.httpCodec != null && !sameConnection(request.url())) {
throw new IllegalStateException("network interceptor " + interceptors.get(index - 1)
+ " must retain the same host and port");
}
// If we already have a stream, confirm that this is the only call to chain.proceed().
//如果我们已经有一个stream, 确定chain.proceed()唯一的call
if (this.httpCodec != null && calls > 1) {
throw new IllegalStateException("network interceptor " + interceptors.get(index - 1)
+ " must call proceed() exactly once");
}
// Call the next interceptor in the chain.
//调用链的下一个拦截器
RealInterceptorChain next = new RealInterceptorChain(
interceptors, streamAllocation, httpCodec, connection, index + 1, request);
Interceptor interceptor = interceptors.get(index);
Response response = interceptor.intercept(next);
// Confirm that the next interceptor made its required call to chain.proceed().
if (httpCodec != null && index + 1 < interceptors.size() && next.calls != 1) {
throw new IllegalStateException("network interceptor " + interceptor
+ " must call proceed() exactly once");
}
// Confirm that the intercepted response isn't null.
if (response == null) {
throw new NullPointerException("interceptor " + interceptor + " returned null");
}
return response;
}
1、创建Retrofit
Retrofit retrofit = new Retrofit.Builder().baseUrl("").build();
Builder()源码:
其作用:
1. Platform.get()通过反射的方式判断其平台是Android是Java
2. 设置转换器工厂列表 converterFactories
3. 设置Call适配器工厂列表 callAdapterFactories
Builder(Platform platform) {
this.converterFactories = new ArrayList();
this.callAdapterFactories = new ArrayList();
this.platform = platform;
}
public Builder() {
this(Platform.get());
}
2. 代理模式,创建动态代理类
RxHttpService apiStores = retrofit.create(RxHttpService.class);
crete()源码:
其作用:
1. eagerlyValidateMethods()验证所有service类中所有的方法
2. 获取一个代理实例,通过反射的方法暴露invoke()可以调用所有的方法
ServiceMethod:Method的所有列表,之前会有个缓存列表serviceMethodCache判断Method是否存在
public T create(final Class service) {
Utils.validateServiceInterface(service);
if(this.validateEagerly) {
this.eagerlyValidateMethods(service);
}
return Proxy.newProxyInstance(service.getClassLoader(), new Class[]{service}, new InvocationHandler() {
private final Platform platform = Platform.get();
public Object invoke(Object proxy, Method method, @Nullable Object[] args) throws Throwable {
if(method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
} else if(this.platform.isDefaultMethod(method)) {
return this.platform.invokeDefaultMethod(method, service, proxy, args);
} else {
ServiceMethod
3.CallAdapter
Request装换成OkHttpCall
4. execute()和enqueue()
同步和异步的方式将OkHttpCall抛给OkHttp执行,具体流程见上面(OkHttp请求步骤)