首先要知道Retrofit 只是一个封装的网络框架,而非网络请求本身。
一个简单的网络请求示例
retrofit = new Retrofit.Builder()
.baseUrl("https://www.wanandroid.com")
.addConverterFactory(GsonConverterFactory.create())
.client(httpClient.build())
.build();
ApiStores apiStore =retrofit.create(ApiStores.class);
Call<HomeDetailJson> call = apiStore.getHomeDetail();
call.enqueue(new Callback<HomeDetailJson>() {
@Override
public void onResponse(Call<HomeDetailJson> call, Response<HomeDetailJson> response) {
Log.d(TAG, "onResponse-->");
HomeDetailJson json = response.body();
}
@Override
public void onFailure(Call<HomeDetailJson> call, Throwable t) {
Log.d(TAG, "onFailure-->" + t.toString());
}
});
其中ApiStore.class 是网络请求api,最终会通过层层解析,对应到ServiceManager类中
public interface ApiStores {
@GET("/article/list/0/json")
Call<HomeDetailJson> getHomeDetail();
}
在这个Retrofit 框架中最重要也是必须要理解的设计模式是动态代理模式,如果有同学不理解的,先去看一下动态代理设计模式。
总而言之,就是apiStore.getHomeDetail()转为生成的动态代理类中去处理了。
现在我们开始扒源码
- new Retrofit.Builder()
public Builder() {
this(Platform.get());
}
Builder(Platform platform) {
this.platform = platform;
}
在new Builder的过程中,主要是找到了对应的platform变量
private static final Platform PLATFORM = findPlatform();
static Platform get() {//单利模式
return PLATFORM;
}
private static Platform findPlatform() {
try {
Class.forName("android.os.Build");
if (Build.VERSION.SDK_INT != 0) {
return new Android();
}
} catch (ClassNotFoundException ignored) {
}
try {
Class.forName("java.util.Optional");
return new Java8();
} catch (ClassNotFoundException ignored) {
}
return new Platform();
}
其实就是不同的平台返回不同的类,在Android 平台下对应的Platform 就是Android()
-
baseUrl("www.wanandroid.com") 这段就不带着去看源码了,其实就是构造出okHttp 中使用的HttpUrl
-
addConverterFactory(GsonConverterFactory.create()) 数据解析使用
public Builder addConverterFactory(Converter.Factory factory) {
converterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
//一个判空检查
GsonConverterFactory.create(),一个使用Gson 做数据解析的类
public static GsonConverterFactory create() {
return create(new Gson());
}
public static GsonConverterFactory create(Gson gson) {
return new GsonConverterFactory(gson);
}
private final Gson gson;
private GsonConverterFactory(Gson gson) {
if (gson == null) throw new NullPointerException("gson == null");
this.gson = gson;
}
- client(httpClient.build())
public Builder callFactory(okhttp3.Call.Factory factory) {
this.callFactory = checkNotNull(factory, "factory == null");
return this;
}
//指定了网络请求框架使用okHttp,其实Android 平台默认也是使用OKHttp 但是因为我要做网络log 日志打印,所以自己设置了一下
- build() 这个方法主要是完成变量的赋值操作,我们挑一些重要的变量来看一下
public Retrofit build() {
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
//设置网络请求框架,默认是OkHttp
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
//回调执行器: MainThreadExecutor
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
//网络请求适配器,转换成不同平台试用的网络请求执行器:ExecutorCallAdapterFactory
// Make a defensive copy of the converters.
List<Converter.Factory> converterFactories = new ArrayList<>(
1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());
//数据解析适配器
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
- 重点来了,最重要的设计模式:代理模式。感觉这个是Retrofit 的灵魂,哇哈哈 retrofit.create(ApiStores.class);通过调用生成代理类,我们解析一下生成代理类的过程。
public <T> T create(final Class<T> service) {
//我们直接看return方法,调用了Proxy.newProxyInstance()这个方法就是用来动态生成代理类,
//此处推荐一篇动态代理的文章 https://blog.csdn.net/lovejj1994/article/details/78080124,相信大家看完这篇文章就知道newProxyInstance 到底做了什么,以及生成了一个什么样的动态代理类。
//最终的结果:Interface中对动态method 的调用都会走下面的invoke 方法。
//那么在代理的解析过程中都发生了什么呢?
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() {
private final Platform platform = Platform.get();
private final Object[] emptyArgs = new Object[0];
@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) {//object class 中定义的方法
return method.invoke(this, args);
}
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
//重点看下面这个方法
return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
}
});
}
loadServiceMethod()有一个很重要的作用就是生成网络请求对象 ServiceManager
//做了优化,会根据Method 做缓存
private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();
ServiceMethod<?> loadServiceMethod(Method method) {
ServiceMethod<?> result = serviceMethodCache.get(method);
//从缓存中获取对应的ServiceManager 对象
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = ServiceMethod.parseAnnotations(this, method);
serviceMethodCache.put(method, result);
}
}
return result;
}
从上面画的这个不规范的时序图可以看出,最终生成了HttpServiceMethod 这个类,
那invoke()方法也就调到对应的类中来看做了什么事情
@Override ReturnT invoke(Object[] args) {
return callAdapter.adapt(
new OkHttpCall<>(requestFactory, args, callFactory, responseConverter));
}
callAdapter 从上面的时序图中,可以得出对应的实际类是ExecutorCallAdapterFactory 中通过get()方法new CallAdapter,那adapt()方法的调用也就是返回了ExecutorCallBackCall
- call.enqueue 也就是ExecutorCallBackCall.enqueue
@Override public void enqueue(final Callback<T> callback) {
checkNotNull(callback, "callback == null");
//从上面的源码分析可得出delegate 对应的是OkHttpCall,所以下面的enqueue转向了OkHttp网络请求框架的逻辑,此处不再分析
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()) {
// Emulate OkHttp's behavior of throwing/delivering an IOException on cancellation.
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);
}
});
}
});
}