寫(xiě)在前面
retrofit源碼版本2.4.0
前置知識(shí): Java動(dòng)態(tài)代理
從用法開(kāi)始
代碼來(lái)自http://www.itdecent.cn/p/021a2c6e128b
public interface RetrofitService {
/**
* 獲取快遞信息
* Rx方式
*
* @param type 快遞類(lèi)型
* @param postid 快遞單號(hào)
* @return Observable<PostInfo>
*/
@GET("query")
Observable<PostInfo> getPostInfoRx(@Query("type") String type, @Query("postid") String postid);
}
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://www.kuaidi100.com/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create()) // 支持RxJava
.build();
RetrofitService service = retrofit.create(RetrofitService.class);
Observable<PostInfo> observable = service.getPostInfoRx("yuantong", "11111111111");
observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<PostInfo>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(PostInfo postInfo) {
Log.i("http返回:", postInfo.toString() + "");
}
});
問(wèn)題有三個(gè):
- 為什么只是寫(xiě)接口Service就可以實(shí)現(xiàn)網(wǎng)絡(luò)請(qǐng)求, 這個(gè)邏輯是怎樣的?
- 返回對(duì)象是怎么轉(zhuǎn)成Observable的?
- 返回對(duì)象ResponseBody怎么通過(guò)Gson轉(zhuǎn)成泛型對(duì)象的?
源碼梳理
Retrofit
Retrofit#create
public <T> T create(final Class<T> service) {
//檢查service是否是接口類(lèi)型, 并且service不允許繼承其它接口
Utils.validateServiceInterface(service);
//是否提前加載service中的所有方法信息
if (validateEagerly) {
eagerlyValidateMethods(service);
}
//動(dòng)態(tài)代理
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) {
//如果調(diào)用的是Object中的方法, 則直接調(diào)用該方法
return method.invoke(this, args);
}
//是否是平臺(tái)的默認(rèn)方法
//Platform是接口, 有Android和Java8兩個(gè)實(shí)現(xiàn)類(lèi)
//上面的Platform.get()方法會(huì)判斷當(dāng)前的系統(tǒng)類(lèi)型
//之所以這么處理, 是因?yàn)橄馢ava8那樣, 接口中是支持默認(rèn)方法的
//如果是默認(rèn)方法, 就直接調(diào)用
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
//加載方法信息(方法參數(shù)/返回值類(lèi)型/注解信息等)
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
//生成OkHttpCall并調(diào)用執(zhí)行
return serviceMethod.adapt(okHttpCall);
}
});
}
這里重點(diǎn)就是最后的三行方法.
Retrofit#loadServiceMethod
//動(dòng)態(tài)代理前面執(zhí)行的這個(gè)方法
//遍歷service中的全部public方法執(zhí)行l(wèi)oadServiceMethod
private void eagerlyValidateMethods(Class<?> service) {
Platform platform = Platform.get();
for (Method method : service.getDeclaredMethods()) {
if (!platform.isDefaultMethod(method)) {
loadServiceMethod(method);
}
}
}
//serviceMethodCache緩存信息
ServiceMethod<?, ?> loadServiceMethod(Method method) {
//serviceMethodCache的類(lèi)型是Map<Method, ServiceMethod<?, ?>>
//如果已經(jīng)加載過(guò), 就從serviceMethodCache取出直接返回
//這也就是執(zhí)行eagerlyValidateMethods的意義
//提前加載
ServiceMethod<?, ?> result = serviceMethodCache.get(method);
if (result != null) return result;
//保證線(xiàn)程按全
//這里是不是很像單例里的雙檢鎖/雙重校驗(yàn)鎖(DCL)
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
//如果沒(méi)加載過(guò), 就創(chuàng)建ServiceMethod
//ServiceMethod這里就是保存方法的各個(gè)信息
result = new ServiceMethod.Builder<>(this, method).build();
//緩存進(jìn)serviceMethodCache
serviceMethodCache.put(method, result);
}
}
return result;
}
ServiceMethod
ServiceMethod.Builder<>(this, method).build()
Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
this.method = method;
//獲取方法的注解信息, 注解可以有多個(gè), 所以是數(shù)組
//比如注解@Get @NotNull
this.methodAnnotations = method.getAnnotations();
//方法的參數(shù)類(lèi)型
this.parameterTypes = method.getGenericParameterTypes();
//方法的參數(shù)中的注解
this.parameterAnnotationsArray = method.getParameterAnnotations();
}
public ServiceMethod build() {
//獲取callAdapter
//注意這個(gè)方法, 該方法和問(wèn)題2有關(guān)
callAdapter = createCallAdapter();
responseType = callAdapter.responseType();
if (responseType == Response.class || responseType == okhttp3.Response.class) {
throw methodError("'"
+ Utils.getRawType(responseType).getName()
+ "' is not a valid response body type. Did you mean ResponseBody?");
}
//注意這個(gè)方法, 該方法和問(wèn)題3有關(guān)
responseConverter = createResponseConverter();
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
//...各種檢查
//Builder模式
//最終生成ServiceMethod, 將builder中的各個(gè)參數(shù)保存到ServiceMethod中
return new ServiceMethod<>(this);
}
看到這里我們大概可以看出, 接口Service中的方法信息被一一對(duì)應(yīng)保存在了對(duì)應(yīng)的ServiceMethod中.
ServiceMethod#adapt
現(xiàn)在回到Retrofit#create方法的最后, 我們調(diào)用了如下方法
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
//這里尤其要注意的是, adapt的參數(shù)是Call的實(shí)現(xiàn)類(lèi), OkHttpCall, 后面還要用到
return serviceMethod.adapt(okHttpCall);
下面我們就來(lái)看看 ServiceMethod#adapt
T adapt(Call<R> call) {
return callAdapter.adapt(call);
}
ServiceMethod#adapt方法很簡(jiǎn)單, 就是調(diào)用了CallAdapter#adapt, 而CallAdapter是接口, 這個(gè)時(shí)候我們就需要來(lái)看看這個(gè)callAdapter到底是誰(shuí)了
在ServiceMethod.Builder#build方法中, 我們創(chuàng)建了callAdapter
callAdapter = createCallAdapter();
private CallAdapter<T, R> createCallAdapter() {
//拿到方法的返回值信息
Type returnType = method.getGenericReturnType();
if (Utils.hasUnresolvableType(returnType)) {
throw methodError(
"Method return type must not include a type variable or wildcard: %s", returnType);
}
if (returnType == void.class) {
throw methodError("Service methods cannot return void.");
}
Annotation[] annotations = method.getAnnotations();
try {
//noinspection unchecked
//最終, 我們的callAdapter是在retrofit類(lèi)中獲取
return (CallAdapter<T, R>) retrofit.callAdapter(returnType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(e, "Unable to create call adapter for %s", returnType);
}
}
Retrofit#callAdapter
public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
}
public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
checkNotNull(returnType, "returnType == null");
checkNotNull(annotations, "annotations == null");
int start = callAdapterFactories.indexOf(skipPast) + 1;
//遍歷callAdapterFactories, 一個(gè)一個(gè)去找
//找到就返回
for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
//...
//如果沒(méi)找到, 輸出異常信息
}
如果我們看一下callAdapterFactories, 就會(huì)發(fā)現(xiàn), 這個(gè)Map里的值正是我們?cè)趧?chuàng)建Retrofit的時(shí)候通過(guò)retrofit2.Retrofit.Builder#addCallAdapterFactory方法傳進(jìn)去的RxJavaCallAdapterFactory.create(), 該方法創(chuàng)建了RxJavaCallAdapterFactory, 也就是說(shuō), 通過(guò)retrofit2.adapter.rxjava.RxJavaCallAdapterFactory#get方法, 我們獲取到了真正的CallAdapter
RxJavaCallAdapterFactory#get
@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
Class<?> rawType = getRawType(returnType);
boolean isSingle = rawType == Single.class;
boolean isCompletable = rawType == Completable.class;
//如果方法的返回值類(lèi)型不是Observable, 也不是Single和Completable
//就返回空
//也就是不由RxJavaCallAdapter處理
if (rawType != Observable.class && !isSingle && !isCompletable) {
return null;
}
//最后, 返回的是RxJavaCallAdapter
if (isCompletable) {
return new RxJavaCallAdapter(Void.class, scheduler, isAsync, false, true, false, true);
}
//...
return new RxJavaCallAdapter(responseType, scheduler, isAsync, isResult, isBody, isSingle,
false);
}
也即是, 真正的CallAdapter其實(shí)是RxJavaCallAdapter
RxJavaCallAdapter#adapt
現(xiàn)在我們重新回頭來(lái)看retrofit2.ServiceMethod#adapt
T adapt(Call<R> call) {
return callAdapter.adapt(call);
}
我們知道了這里callAdapter是RxJavaCallAdapter, 參數(shù)call是OkHttpCall
所以我們來(lái)看RxJavaCallAdapter#adapt
//注意, 這里, 也是問(wèn)題2的關(guān)鍵
@Override public Object adapt(Call<R> call) {
//如果是異步方法, 就返回CallEnqueueOnSubscribe, 如果是同步, 就返回CallExecuteOnSubscribe
OnSubscribe<Response<R>> callFunc = isAsync
? new CallEnqueueOnSubscribe<>(call)
: new CallExecuteOnSubscribe<>(call);
OnSubscribe<?> func;
if (isResult) {
func = new ResultOnSubscribe<>(callFunc);
} else if (isBody) {
func = new BodyOnSubscribe<>(callFunc);
} else {
func = callFunc;
}
Observable<?> observable = Observable.create(func);
if (scheduler != null) {
observable = observable.subscribeOn(scheduler);
}
if (isSingle) {
return observable.toSingle();
}
if (isCompletable) {
return observable.toCompletable();
}
return observable;
}
final class CallEnqueueOnSubscribe<T> implements OnSubscribe<Response<T>> {
private final Call<T> originalCall;
CallEnqueueOnSubscribe(Call<T> originalCall) {
this.originalCall = originalCall;
}
@Override public void call(Subscriber<? super Response<T>> subscriber) {
// Since Call is a one-shot type, clone it for each new subscriber.
Call<T> call = originalCall.clone();
final CallArbiter<T> arbiter = new CallArbiter<>(call, subscriber);
subscriber.add(arbiter);
subscriber.setProducer(arbiter);
//這里, 執(zhí)行了OkHttpCall#enqueue, 拿到返回值后, 通過(guò)arbiter發(fā)射出去
call.enqueue(new Callback<T>() {
@Override public void onResponse(Call<T> call, Response<T> response) {
arbiter.emitResponse(response);
}
@Override public void onFailure(Call<T> call, Throwable t) {
Exceptions.throwIfFatal(t);
arbiter.emitError(t);
}
});
}
}
以異步為例, 如果簡(jiǎn)單些, 可以如下
Observable.create(new Observable.OnSubscribe<T>() {
@Override
public void call(Subscriber<T> subscriber) {
call.enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
subscriber.onNext(response);
}
@Override
public void onFailure(Call call, Throwable t) {
subscriber.onError(t);
}
});
}
});
到這里, 我們就可以回答問(wèn)題2了.
Retrofit通過(guò)動(dòng)態(tài)代理實(shí)現(xiàn)了接口中的方法, 在方法的最后, 使用了RxJavaCallAdapter#adapt方法來(lái)獲取結(jié)果, 而RxJavaCallAdapter#adapt做的也就是通過(guò)Observable.create創(chuàng)建Observable, 在調(diào)用OkHttpCall#enqueue方法拿到返回的結(jié)果后, 通過(guò)Observable發(fā)射出去, 生成Observable的數(shù)據(jù)流. 這樣就把生成的結(jié)果轉(zhuǎn)成了Observable.
在上面的異步方法中, 我們實(shí)際上通過(guò)retrofit2.Call#enqueue來(lái)獲取請(qǐng)求結(jié)果, 而這里的Call, 實(shí)際上是OkHttpCall, 所以, 我們來(lái)看下OkHttpCall#enqueue
OkHttpCall
OkHttpCall中有OkHttpCall#enqueue和OkHttpCall#execute, 分別對(duì)應(yīng)異步方法和同步方法
我們這里只說(shuō)OkHttpCall#enqueue
OkHttpCall#enqueue
//如果callback為空, 拋出異常
checkNotNull(callback, "callback == null");
//...檢查各個(gè)參數(shù)
//這里, 才是真正的調(diào)用了Okhttp的enqueue方法
//調(diào)用OkHttp的enqueue異步方法, 獲取結(jié)果
call.enqueue(new okhttp3.Callback() {
@Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
Response<T> response;
try {
response = parseResponse(rawResponse);
} catch (Throwable e) {
callFailure(e);
return;
}
try {
callback.onResponse(OkHttpCall.this, response);
} catch (Throwable t) {
t.printStackTrace();
}
}
@Override public void onFailure(okhttp3.Call call, IOException e) {
callFailure(e);
}
private void callFailure(Throwable e) {
try {
callback.onFailure(OkHttpCall.this, e);
} catch (Throwable t) {
t.printStackTrace();
}
}
});
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
//...
//解析返回結(jié)果
//這里也是問(wèn)題3的關(guān)鍵
ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);
try {
//解析結(jié)果
//泛型解析
//這里跟我們創(chuàng)建Retrofit的時(shí)候通過(guò)addConverterFactory(GsonConverterFactory.create(gson)對(duì)應(yīng)
T body = serviceMethod.toResponse(catchingBody);
return Response.success(body, rawResponse);
} catch (RuntimeException e) {
// If the underlying source threw an exception, propagate that rather than indicating it was
// a runtime exception.
catchingBody.throwIfCaught();
throw e;
}
}
所以, 問(wèn)題3就是, 在OkHttpCall中, 拿到返回結(jié)果后, 將結(jié)果交給創(chuàng)建Retrofit的時(shí)候通過(guò)addConverterFactory(GsonConverterFactory.create(gson)生成的對(duì)應(yīng)的GsonConvert, 轉(zhuǎn)成對(duì)應(yīng)的對(duì)象
重新梳理
這里, 我們回國(guó)頭來(lái)重新看
public <T> T create(final Class<T> service) {
//...
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() {
@Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)
throws Throwable {
//...
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.adapt(okHttpCall);
}
});
}
- 首先通過(guò)動(dòng)態(tài)代理, 生成對(duì)應(yīng)接口的實(shí)現(xiàn)類(lèi). 調(diào)用接口中的方法時(shí), 執(zhí)行動(dòng)態(tài)代理的invoke方法
- ServiceMethod<Object, Object> serviceMethod = (ServiceMethod<Object, Object>) loadServiceMethod(method);
方法, 獲取接口中方法的信息(方法返回值類(lèi)型/注解信息/參數(shù)類(lèi)型/參數(shù)注解等) - 創(chuàng)建OkHttpCall(封裝Okttp中的Call為OkHttpCall)
- 執(zhí)行CallAdapter#adapter(這里的CallAdapter實(shí)際為RxJavaCallAdapter), 在RxJavaCallAdapter#adapter中執(zhí)行OkHttpCall#enqueue(以異步為例)執(zhí)行網(wǎng)絡(luò)請(qǐng)求, 并用Observable將結(jié)果發(fā)射出去成為Observable