首先要知道Retrofit 只是一個封裝的網絡框架,而非網絡請求自己。java
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類中android
public interface ApiStores {
@GET("/article/list/0/json")
Call<HomeDetailJson> getHomeDetail();
}
複製代碼
在這個Retrofit 框架中最重要也是必需要理解的設計模式是動態代理模式,若是有同窗不理解的,先去看一下動態代理設計模式。json
總而言之,就是apiStore.getHomeDetail()轉爲生成的動態代理類中去處理了。設計模式
public Builder() {
this(Platform.get());
}
Builder(Platform platform) {
this.platform = platform;
}
複製代碼
在new Builder的過程當中,主要是找到了對應的platform變量api
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 中使用的HttpUrlbash
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;
}
複製代碼
public Builder callFactory(okhttp3.Call.Factory factory) {
this.callFactory = checkNotNull(factory, "factory == null");
return this;
}
//指定了網絡請求框架使用okHttp,其實Android 平臺默認也是使用OKHttp 可是由於我要作網絡log 日誌打印,因此本身設置了一下
複製代碼
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);
}
複製代碼
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()有一個很重要的做用就是生成網絡請求對象 ServiceManageride
//作了優化,會根據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
@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); } }); } }); } 複製代碼