Retrofit 分析
先上一个RetrofitHelper 使用kotlin的默认单例模式
object RetrofitHelper {
private var mOkHttpClient: OkHttpClient? = null
fun getGankApiService() = createApi(GankApi::class.java, "http://gank.io/")
private fun <T> createApi(clazz: Class<T>, baseUrl: String): T {
if (mOkHttpClient == null)
initOkHttpClient()
val retrofit = Retrofit.Builder()
.baseUrl(baseUrl)
.client(mOkHttpClient!!)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build()
return retrofit.create(clazz)
}
private fun initOkHttpClient() {
val httpLoggingInterceptor = HttpLoggingInterceptor()
httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
if (mOkHttpClient == null) {
synchronized(RetrofitHelper::class.java) {
if (mOkHttpClient == null) {
//val cache = Cache(File(.getCacheDir(), "HttpCache"), 1024 * 1024 * 1)
mOkHttpClient = OkHttpClient.Builder()
//.cache(cache)
.addInterceptor(httpLoggingInterceptor)
.retryOnConnectionFailure(true)
.connectTimeout(30, TimeUnit.SECONDS)
.writeTimeout(20, TimeUnit.SECONDS)
.readTimeout(20, TimeUnit.SECONDS)
.build()
}
}
}
}
}
Retrofit.java中create方法
public <T> T create(final Class<T> service) {
Utils.validateServiceInterface(service);
if (validateEagerly) {
eagerlyValidateMethods(service);
}
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() {
private final Platform platform = Platform.get();
@Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)
throws Throwable {
// If the method is a method from Object then defer to normal invocation.
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.adapt(okHttpCall);
}
});
}
create 先先检查service,不是接口报错,接口有继承也报错
返回 动态代理代理接口,加入回掉
1.确定平台,安卓平台
2.如果是object类的方法直接调用
3.平台默认方法(不支持,一直返回false)
4.新建ServiceMethod,把一个接口转换到一个httpcall
ServiceMethod<?, ?> loadServiceMethod(Method method) {
ServiceMethod<?, ?> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = new ServiceMethod.Builder<>(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
}
5.ServiceMethod的build方法 新建callAdapter,到retrofit的callAdapterFactories抽象工厂缓存里用get生产实例
6.callAdapter的返回类型才是最终的返回类型
7.生成responseConverter,类似上面也是抽象工厂从retrofit缓存生产转换器
8.后续 把方法注解路径等都抽出来转换到内置属性
9.OkHttpCall用ServiceMethod来构造,由okhttpclient生产
10.OkHttpCall是okhttp3.Call的泛型版本,okhttp3.Call嵌套调用OkHttpCall的onresponse和onFailure;返回还会被parseResponse做成功转换
11.默认calladapter情况下serviceMethod.adapt(okHttpCall) 返回okHttpCall
addCallAdapterFactory(RxJava2CallAdapterFactory.create())
callAdapterFactories抽象工厂模式 get生产实例
nextCallAdapter里获得callAdapterFactories中第一个的CallAdapter,先自定义后默认
RxJava2CallAdapter的adapt新建Observable
OKHTTP3
newcall新建realcall代表一次请求,
enqueue异步任务的时候交给clinet的Dispatcher的enqueue
enqueue的是一个runnable (子类实现AsyncCall)交给线程池
异步任务使用Dispatcher处理,内部主要是一个线程池,不保留存活60秒无限数量
public synchronized ExecutorService executorService() {
if (executorService == null) {
executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(), Util.threadFactory("OkHttp Dispatcher", false));
}
return executorService;
}
AsyncCall的run调用execute 是异步发生的callback
@Override protected void execute() {
boolean signalledCallback = false;
try {
Response response = getResponseWithInterceptorChain();
if (retryAndFollowUpInterceptor.isCanceled()) {
signalledCallback = true;
responseCallback.onFailure(RealCall.this, new IOException("Canceled"));
} else {
signalledCallback = true;
responseCallback.onResponse(RealCall.this, response);
}
} catch (IOException e) {
if (signalledCallback) {
// Do not signal the callback twice!
Platform.get().log(INFO, "Callback failure for " + toLoggableString(), e);
} else {
eventListener.callFailed(RealCall.this, e);
responseCallback.onFailure(RealCall.this, e);
}
} finally {
client.dispatcher().finished(this);
}
}
response使用了责任链设计模式
1.内部添加了多个拦截器的ArrayList
2.使用index作为索引,调用第一个chain的proceed
3.RealInterceptorChain作为实现,proceed的时候先检查index是否越界(执行结束)
4.新建下一个RealInterceptorChain并传入index+1的位置
5.使用当前的Interceptor 处理下一个RealInterceptorChain;其实就是执行当前的Interceptor的intercept方法,主要内容:用当前Interceptor修改下一个RealInterceptorChain,然后调用下一个RealInterceptorChain的proceed方法,循环处理。(ConnectInterceptor 添加了HttpCodec 传给了下游的CallServerInterceptor)
6.CallServerInterceptor是最后一个拦截器负责请求数据,只会被倒数第二个调用,不再调用下一个了
7.HttpCodec有http1和2的各自实现,CallServerInterceptor联网的过程是用HttpCodec的高层次接口实现的
8.interface HttpCodec接口的实现,最终交给Okio来处理(Sink)
9.对网络的处理,最终是socket的java.io.OutputStream java实现