Retrofit(OkHttp)源码分享
一、使用
1.创建接口
public interface CountTryApi {
@GET("/api/location/country")
Call<ResponseBody> getCall(@Query("id") String id);
}
2.发起请求
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://***.com/") // 设置网络请求的公共Url地址
//.addConverterFactory(GsonConverterFactory.create()) // 设置数据解析器
//.addCallAdapterFactory(RxJavaCallAdapterFactory.create()) // 支持RxJava
.build();
// 创建网络请求接口的实例
CountTryApi request = retrofit.create(CountTryApi.class);
// 调用方法,对发送请求进行封装
Call<ResponseBody> call = request.getCall("1111");
/发送网络请求(异步)
call.enqueue(new Callback<ResultData>() {
//请求成功时回调
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
//处理结果
}
//请求失败时候的回调
@Override
public void onFailure(Call<ResponseBody> call, Throwable throwable) {
//提示失败
}
});
// 发送网络请求(同步)
Response<ResultData> response = call.execute();
二、执行流程
1. 创建Retrofit实例
使用Build设计模式,retrofit中主要参数:
- convertFactories:转换结果,可自定义,如addConverterFactory.add(GsonConverterFactory.create())
- callFactoty:OkHttpClient(创建连接池connectionPool)
- callbackExecutor:切换主线程执行
- adapterFactories:请求和回调,可自定义,addCallAdapterFactory(RxJava2CallAdapterFactory.create())
看下我们自定义的addConverterFactory和addCallAdapterFactory执行顺序,执行过程在构造ServiceMethod中
// 先调addCallAdapterFactory,所以我们定义的是加在第0个的
adapter.List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
List<Converter.Factory> converterFactories = new ArrayList<>(1 + this.converterFactories.size());
// 第0个是BuiltInConverters,之后是我们添加的converterFactory
converterFactories.add(new BuiltInConverters());
converterFactories.addAll(this.converterFactories);
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories), unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
callAdapterFactory在使用时
// start = 0,
int start = callAdapterFactories.indexOf(null) + 1;
for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
从第0个开始,找到CallAdapter就返回,所以使用的是我们第一个调用addCallAdapterFactory添加的
converterFactories在使用时:
// start = 0
int start = converterFactories.indexOf(null) + 1;
for (int i = start, count = converterFactories.size(); i < count; i++) {
Converter<ResponseBody, ?> converter = converterFactories.get(i).responseBodyConverter(type, annotations, this);
if (converter != null) {
return (Converter<ResponseBody, T>) converter;
}
}
第0个是BuiltInConverters,返回类型是ResponseBody或Void返回对应的converter,否则返回null,返回null就会继续遍历到我们自定义的Converter,所以我们也可以自定义转换某些类型的ConverterFactory,在第一个addConverterFactory添加进来,对于不是这些类型的返回null,再继续遍历后续add的ConverterFactory
2. Retrofit.create返回定义接口代理对象
使用动态代理,返回Proxy.newProxyInstance创建的代理对象,实现invoke方法
动态代理:
public interface TestInterface {
String getInterface();
}
public class TestProxy {
public staic void main(String[] args) {
TestInterface proxy = createProxy();
System.out.println("\"getInterface\" result: " + proxy.getInterface());
System.out.println("proxy class: " + proxy.getClass());
System.out.println("proxy super class: " + proxy.getClass().getSuperclass());
}
private TestInterface createProxy() {
return (TestInterface) Proxy.newProxyInstance(TestInterface.class.getClassLoader(), new Class[]{TestInterface.class}, (InvocationHandler) (proxy, method, args) -> {
System.out.println("invoke method: " + method.getName());
return "TestInterface";
});
}
}
执行结果
invoke method: getInterface
"getInterface" result: TestInterface
proxy class: class com.sun.proxy.$Proxy4
proxy super class: class java.lang.reflect.Proxy
代理对象实际类型是$Proxy4,代理类是动态构造类信息,生成class文件
生成代理类的源码执行过程
Proxy.newProxyInstance -> Proxy.getProxyClass0 -> WeakCache.get -> Factory.apply -> Factory.get
-> ProxyClassFactory.apply,主要生成class对象的逻辑在ProxyClassFactory.apply,Class对象就是ProxyClassFactory.apply返回的
ProxyClassFactory.apply部分代码
long num = nextUniqueNumber.getAndIncrement();
// proxyPkg包名,默认"com.sun.proxy."
// proxyClassNamePrefix 常量"$Proxy"
// num 自增int
String proxyName = proxyPkg + proxyClassNamePrefix + num;
return generateProxy(proxyName, interfaces, loader, methodsArray,
exceptionsArray);
generateProxy是个native方法,我们看Proxy.class中ProxyClassFactory.apply最后这段代码:
long var19 = nextUniqueNumber.getAndIncrement();
String var23 = var16 + "$Proxy" + var19;
// var23 类名 proxyName
// var2 newProxyInstance传的第二个参数 Class[]
// var accessFlags
// 动态生成class文件
byte[] var22 = ProxyGenerator.generateProxyClass(var23, var2, var17);
try {
// 加载字节码,并返回对应的class对象
return Proxy.defineClass0(var1, var23, var22, 0, var22.length);
} catch (ClassFormatError var14) {
throw new IllegalArgumentException(var14.toString());
}
generateProxyClass调用ProxyGenerator.generateClassFile
private byte[] generateClassFile() {
// 添加Object的方法,使调用这些方法也走invoke
this.addProxyMethod(hashCodeMethod, Object.class);
this.addProxyMethod(equalsMethod, Object.class);
this.addProxyMethod(toStringMethod, Object.class);
...
// 添加自己写的方法到proxyMethods
for(var3 = 0; var3 < var2; ++var3) {
Method[] var5 = var4.getMethods();
for(int var7 = 0; var7 < var6; ++var7) {
Method var8 = var5[var7];
this.addProxyMethod(var8, var4);
}
}
// 生成构造函数并添加到method
this.methods.add(this.generateConstructor());
// 遍历上述添加的proxyMethods,动态生成method(内部执行到invoke)
var11 = this.proxyMethods.values().iterator();
while(var11.hasNext()) {
var12 = (List)var11.next();
var15 = var12.iterator();
while(var15.hasNext()) {
// ...
this.methods.add(var16.generateMethod());
}
}
// 添加静态字段的初始化
this.methods.add(this.generateStaticInitializer());
...
// 把生成的类信息写到文件中
var14.writeShort(this.cp.getClass(dotToSlash(this.className)));
...
}
return var4;
}
generateConstructor部分代码
// 生成init方法,构造函数
ProxyGenerator.MethodInfo var1 = new ProxyGenerator.MethodInfo("<init>", "(Ljava/lang/reflect/InvocationHandler;)V", 1);
DataOutputStream var2 = new DataOutputStream(var1.code);
...
return var1;
generateMethod方法部分代码
String var1 = ProxyGenerator.getMethodDescriptor(this.parameterTypes, this.returnType);
ProxyGenerator.MethodInfo var2 = ProxyGenerator.this.new MethodInfo(this.methodName, var1, 17);
DataOutputStream var9 = new DataOutputStream(var2.code);
var9.writeShort(ProxyGenerator.this.cp.getFieldRef("java/lang/reflect/Proxy", "h", "Ljava/lang/reflect/InvocationHandler;"));
// 调用的invoke
var9.writeShort(ProxyGenerator.this.cp.getInterfaceMethodRef("java/lang/reflect/InvocationHandler", "invoke", "(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;"));
generateStaticInitializer部分代码
// 生成clinit,执行静态字段或静态块
ProxyGenerator.MethodInfo var1 = new ProxyGenerator.MethodInfo("<clinit>", "()V", 8);
...
return var1;
生成class对象后,找到InvocationHandler为参数的构造函数,创建实例并返回
Constructor<?> cons = cl.getConstructor(Class[]{ InvocationHandler.class });
return cons.newInstance(new Object[]{h});
生成的$Proxy4类部分代码:
public final class $Proxy4 extends Proxy implements TestInterface {
public $Proxy4(InvocationHandler var1) throws {
super(var1);
}
public final String getInterface() throws {
try {
return (String)super.h.invoke(this, m3, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final String toString() throws {
try {
return (String)super.h.invoke(this, m2, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
}
3. 调用代理方法,返回OkHttpCall对象
调用接口方法,执行代理对象实现的invoke方法,解析接口方法的注解,参数,参数注解,以及参数值
ServiceMethod<Object, Object> serviceMethod = (ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.adapt(okHttpCall);
-
loadServiceMethod,使用Build设计模式,创建ServiceMethod对象
ServiceMethod
1.callAdapter :retrofit.callAdapterFactories.get(0).get(retrunType, annotations, retrofit)
默认返回ExecutorCallAdapterFactory.CallAdapter对象
2.responseType :callAdapter.responseType();
3.responseConverter :retrofit.converterFactories.get(0).responseBodyConverter(type, annotations, this);
4.parseMethodAnnotation解析注解
5.parameterHandlers解析参数的注解
ServiceMethod中包含了请求的信息、执行回调、类型解析,用于后续构造OkHttp.Call
-
创建OkHttpCall
serviceMethod:第1步创建好的ServiceMethod
args:参数值
-
返回Call,默认情况下返回ExecutorCallAdapterFactory.ExecutorCallbackCall
serviceMethod.adapt(okHttpCall)
T adapt(Call<R> call) { // callAdapter 在我们不自己定义adapterFactory时,是默认的platform.defaultCallAdapterFactory(callbackExecutor),就是ExecutorCallAdapterFactory return callAdapter.adapt(call); }
return new CallAdapter<Object, Call<?>>() { public Type responseType() { return responseType; } public Call<Object> adapt(Call<Object> call) { // callbackExecutor 是默认的 MainThreadExecutor,用于切换到主线程 return new ExecutorCallAdapterFactory.ExecutorCallbackCall(ExecutorCallAdapterFactory.this.callbackExecutor, call); } };
4. 开始执行请求
也就是执行ExecutorCallAdapterFactory.ExecutorCallbackCall.enqueue
public void enqueue(final Callback<T> callback) {
// delegate就是上述构造的OkHttpCall
delegate.enqueue(new Callback<T>() {
@Override public void onResponse(Call<T> call, final Response<T> response) {
callbackExecutor.execute(new Runnable() {
@Override public void run() {
if (delegate.isCanceled()) {
callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
} else {
callback.onResponse(ExecutorCallbackCall.this, response);
}
}
});
}
@Override public void onFailure(Call<T> call, final Throwable t) {
callbackExecutor.execute(new Runnable() {
@Override public void run() {
callback.onFailure(ExecutorCallbackCall.this, t);
}
});
}
});
}
// OKHttpCall.enqueue
@Override public void enqueue(final Callback<T> callback) {
okhttp3.Call call;
synchronized (this) {
call = rawCall;
// ...
// 创建RealCall,调用ServiceMethod.toCall,传参args(我们调用方法时的参数值)
// ServiceMethod.callFactory(OkHttpClient).toCall(ServiceMethod中属性组成的Request)
// 返回RealCall
call = rawCall = createRawCall();
}
// ...
// 调用异步执行,传入回调接口
call.enqueue(new okhttp3.Callback() {
@Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
// 解析为返回类型
Response<T> response = parseResponse(rawResponse);
// ...
callback.onResponse(OkHttpCall.this, response);
}
@Override public void onFailure(okhttp3.Call call, IOException e) {
callFailure(e);
}
private void callFailure(Throwable e) {
// ...
callback.onFailure(OkHttpCall.this, e);
}
});
}
RealCall.enqueue
@Override public void enqueue(Callback responseCallback) {
// ...
// AsyncCall也就是一个Runnable
// diapatch 是管理执行Runnable的类,内部有线程池
client.dispatcher().enqueue(new AsyncCall(responseCallback));
}
上面一行执行完后,即调用AsyncCall.execute()方法,里面主要调用了getResponseWithInterceptorChain,代码如下:
Response getResponseWithInterceptorChain() throws IOException {
List<Interceptor> interceptors = new ArrayList<>();
// addInterceptor()添加的拦截器
interceptors.addAll(client.interceptors());
interceptors.add(retryAndFollowUpInterceptor);
interceptors.add(new BridgeInterceptor(client.cookieJar()));
interceptors.add(new CacheInterceptor(client.internalCache()));
interceptors.add(new ConnectInterceptor(client));
if (!forWebSocket) {
// addNetworkInterceptor()添加的拦截器
interceptors.addAll(client.networkInterceptors());
}
interceptors.add(new CallServerInterceptor(forWebSocket));
Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0, originalRequest, this, eventListener, client.connectTimeoutMillis(), client.readTimeoutMillis(), client.writeTimeoutMillis());
return chain.proceed(originalRequest);
}
okHttpClientBuilder.addInterceptor添加的拦截器,在所有操作发生前和请求并处理完成后操作,如添加base params,打印日志
okHttpClientBuilder.addNetWorkInterceptor添加的拦截器,可以处理可在建立连接发起请求之前和发起请求后做操作,如Stetho,修改默认请求头
5. 拦截器
1. RetryAndFollowUpInterceptor
重试机制
2. BridgeInterceptor
请求头,gzip(可用做流量优化),cookieJar
返回的gzip解压
3. CacheInterceptor
使用缓存,用到OKHttp中的DiskLruCache和Okio(可用做流量优化)
4. ConnectInterceptor
建立连接
5. CallServerInterceptor
真正的发送接收数据的过程
-
默认没有缓存,缓存自己定义
// 自己定义缓存的文件 File cacheFile = new File(DemoApplication.getContext().getCacheDir(),"demo_repo"); Cache cache = new Cache(cacheFile, 1024 * 1024 * 50); Interceptor cacheInterceptor = new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); // 没网强制使用缓存 if (!NetworkUtil.isNetworkAvailable(DemoApplication.getContext())) { request = request.newBuilder().cacheControl(CacheControl.FORCE_CACHE).build(); } return chain.proceed(request); }}; builder.cache(cache).addInterceptor(cacheInterceptor);
-
缓存只对GET请求有效,cache无效,即使设置里only-if-cache
// 请求完成后 if (HttpMethod.invalidatesCache(response.request().method())) { try { remove(response.request()); } catch (IOException ignored) { // The cache cannot be written. } return null; } if (!requestMethod.equals("GET")) { return null; } // 缓存完成后 if (cache != null) { if (HttpMethod.invalidatesCache(networkRequest.method())) { ... cache.remove(networkRequest); ... } } public static boolean invalidatesCache(String method) { return method.equals("POST") || method.equals("PATCH") || method.equals("PUT") || method.equals("DELETE") || method.equals("MOVE"); }
-
默认gzip压缩
// Range 告知服务器返回文件的哪一部分 if (userRequest.header("Accept-Encoding") == null && userRequest.header("Range") == null) { transparentGzip = true; requestBuilder.header("Accept-Encoding", "gzip"); }
-
自定义cookieJar
cookieJar的处理过程(源码)
// 加载cookie List<Cookie> cookies = cookieJar.loadForRequest(userRequest.url()); if (!cookies.isEmpty()) { requestBuilder.header("Cookie", cookieHeader(cookies)); } Response networkResponse = chain.proceed(requestBuilder.build()); // 请求完成,保存cookie HttpHeaders.receiveHeaders(cookieJar, userRequest.url(), networkResponse.headers());
自定义cookieJar方式
public class MyCookieJar implements CookieJar { @Override public void saveFromResponse(HttpUrl url, List<Cookie> cookies) { // 服务端返回的 cookie,可保存在本地 } @Override public List<Cookie> loadForRequest(HttpUrl url) { // 从本地加载保存的 cookie return null; } } // 设置自定义 CookieJar OKHttpClient.Build().cookieJar(new MyCookieJar());
-
forWebSocket
RealCall.getResponseWithInterceptorChain添加拦截器时,有一个forWebSocket,它在什么时候是true/false
if (!forWebSocket) {
interceptors.addAll(client.networkInterceptors());
}
forWebSocket是创建RealCall对象构造函数传的参数,我们平时使用传false,使用WebSocket时传false,也就是调用okHttpClient.newWebSocket时。
也就是说,使用WebSocket时,不支持addNetWorkInterceptor.