前言:已經(jīng)有很多的retrofit源碼分析了雾消。為什么還要寫這篇文章呢瞬逊。有幾個目的吧
1、自己記錄下分析過程的心得仪或,加深印象。
2士骤、希望能作為輔助參考幫助到其他學(xué)習(xí)retrofit源碼的人范删。
3、與之前參考過的文章做個相互印證拷肌,也希望各位看到有什么錯誤的理解能提出來到旦,有助于自己改正旨巷。
之前分析過Retrofit,大概的了解了注解和方法在何時被解析添忘。以及動態(tài)代理的妙用采呐。但是最近生出一個問題,gson轉(zhuǎn)化器是什么時候被調(diào)用了搁骑?一時不能給出答案斧吐。這次便帶著這個疑問去看了。
一仲器、從構(gòu)建retrofit實例說起煤率,帶著我的疑問去看(GsonConverter配置以后在什么位置調(diào)用了呢?)
retrofit = new Retrofit.Builder()
.client(EmptyUtils.checkNotNull(client))
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(EmptyUtils.checkNotNull(converterFactory()))
.addCallAdapterFactory(EmptyUtils.checkNotNull(callAdapterFactory()))
.baseUrl(EmptyUtils.checkNotNull(baseUrl()))
.build();
一般來講乏冀,我們會根據(jù) Builder().build()來生成一個Retrofit實例蝶糯。其中包含了各種配置。
(請求的客戶端辆沦。json解析器昼捍,rxjava2calladapter)
當(dāng)我們構(gòu)建出來 retrofit 實例之后,這些配置就被設(shè)置到了retrofit 之中肢扯。下面是builder 的參數(shù)妒茬。
private final Platform platform; //平臺。是java平臺還是Android平臺
private @Nullable okhttp3.Call.Factory callFactory; //client 一般來說我們配置的okhttpclient
private HttpUrl baseUrl; //url地址鹃彻,不多說
//轉(zhuǎn)換器郊闯,addConverterFactory的時候,多個都添加到了這個list中
private final List<Converter.Factory> converterFactories = new ArrayList<>();
//執(zhí)行適配器(我是這么叫的)蛛株,calladapter 通過 addCallAdapterFactory 添加的實例都放入了這個list
private final List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>();
執(zhí)行build的時候团赁,將添加好的配置設(shè)置到了retrofit之中。
public Retrofit build() {
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
// Make a defensive copy of the adapters and add the default Call adapter.
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
// Make a defensive copy of the converters.
List<Converter.Factory> converterFactories =
new ArrayList<>(1 + this.converterFactories.size());
// Add the built-in converter factory first. This prevents overriding its behavior but also
// ensures correct behavior when using converters that consume all types.
converterFactories.add(new BuiltInConverters());
converterFactories.addAll(this.converterFactories);
//將各個參數(shù)傳入構(gòu)造方法谨履,生成retrofit實例欢摄,之前各種add只是將參數(shù)添加到了builder對象中,
//執(zhí)行build才是真正將各個參數(shù)配置給了retrofit對象笋粟。這也是builder模式的使用方法怀挠。
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
生成對象之后,我們會使用retrofit.create(XXXXService.class); //XXXXService是interface類型的害捕。那我們就從create方法去入手绿淋。
public <T> T create(final Class<T> service) {
//1、驗證服務(wù)接口尝盼。 檢驗文件是否是interface類型吞滞。 如果不是拋出異常。
Utils.validateServiceInterface(service);
if (validateEagerly) {
eagerlyValidateMethods(service);
}
//返回類型是通過動態(tài)代理生成的對象。T就是傳入的接口類裁赠。
//動態(tài)代理的invoke方法殿漠,會在每個方法調(diào)用的時候執(zhí)行。也就是xxxxservice.doAction()的時候佩捞;(例子绞幌,假設(shè)doAction是接口中的一個方法);
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() {
//獲取平臺類型。檢查是Android還是Java一忱。我們可以忽略莲蜘,因為開發(fā)Android,平臺類型一般都是Android掀潮。這里會得到一個Android類型的Platform對象菇夸。
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.
//檢查方法是否來自O(shè)bject。如果是就正常調(diào)用仪吧。我們傳入的是接口類庄新,所以這里不會執(zhí)行,直接跳過薯鼠。
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
//這里我們向isDefaultMethod方法里面看择诈,可以看到android平臺的這個方法永遠(yuǎn)返回false。所以此處也是跳過出皇。
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
//這里是重點P呱帧!郊艘!荷科,從這里開始去解析目前正在執(zhí)行的方法。 就是去我們傳入的接口類中纱注,找到當(dāng)前調(diào)用的doAction方法畏浆。同時去解析注解和各種參數(shù)。得到一個ServiceMethod對象狞贱。
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
//用serviceMethod對象生成一個OkHttpCall對象.serviceMethod中有解析到的各種配置刻获。
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
//返回一個對象,如果我們沒有使用rxjava 那么拿到的是call對象瞎嬉。如果使用了rxjava蝎毡。那么拿到的是Observable對象。
//此處拿到的返回對象氧枣,是在xxxxservice.doAction()時得到的對象沐兵。決定返回對象的類型。是在retrofit.builder.addCallAdapterFactory的時候.
return serviceMethod.adapt(okHttpCall);
}
});
}
至此便监。create分析的差不多了扎谎。 到此位置,以rxjava2為例,得到了一個Observable對象簿透。 拿著這個對象可以進(jìn)行后續(xù)的操作。
當(dāng)然還有l(wèi)oadServiceMethod 與serviceMethod.adapt(okHttpCall)兩個方法內(nèi)部沒有分析解藻。這個放到后面補充