基本用法
Retrofit retrofit =new Retrofit.Builder().client(okhttpClient).baseUrl("http://localhost/").addCallAdapterFactory(RxJava2CallAdapterFactory.create()).addConverterFactory(GsonConverterFactory.create()).build();
API api=retrofit.create(API.class);
上面代碼主要?jiǎng)?chuàng)建了Retrofit對(duì)象斤寇,并且為Retrofit對(duì)象分別設(shè)置了OkhttpClient對(duì)象捞蚂、baseUrl福荸、CallAdapterFactory對(duì)象和ConvertFactory對(duì)象腊瑟。最關(guān)鍵的是create方法
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, 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.callAdapter.adapt(okHttpCall);
}
});
}
以上是create方法的全部代碼喂分,只有幾十行锦庸,看著也不是特別復(fù)雜。第一行 Utils.validateServiceInterface(service);從名字就可以知道是用來檢驗(yàn)參數(shù)service是否是一個(gè)接口的蒲祈,不是重點(diǎn)甘萧,不需要重點(diǎn)關(guān)注。第二行validateEagerly默認(rèn)是false,所以第三行不會(huì)執(zhí)行讳嘱,(注:如果我們?cè)跇?gòu)建Retrofit對(duì)象時(shí)設(shè)置了validateEagerly屬性為true,那么第三行eagerlyValidateMethods(service)會(huì)執(zhí)行,這個(gè)方法中會(huì)遍歷接口中所有的方法酿愧,如果不是default方法沥潭,就調(diào)用loadServiceMethod方法,將接口中的所有方法緩存嬉挡,default方法是jdk1.8當(dāng)中引入的钝鸽,在jdk1.8當(dāng)中接口可以有實(shí)現(xiàn)方法,只要在方法前加default關(guān)鍵字)庞钢。在create方法的第五行就直接返回了一個(gè)動(dòng)態(tài)代理對(duì)象拔恰,也就是說create方法實(shí)際就做了兩件事,第一基括、驗(yàn)證參數(shù)是不是接口類型颜懊,第二、返回代理對(duì)象。那么重點(diǎn)關(guān)注的代碼都在代理對(duì)象里面了河爹。Proxy.newProxyInstance方法返回一個(gè)實(shí)現(xiàn)了參數(shù)service接口的對(duì)象匠璧,也就是開頭 API api=retrofit.create(API.class)中的api對(duì)象。根據(jù)動(dòng)態(tài)代理的特性咸这,我們每次調(diào)用api這個(gè)對(duì)象的方法夷恍,其實(shí)調(diào)用的是InvocationHandler當(dāng)中的invoke方法,也就是create方法當(dāng)中第七行的new InvocationHandler()對(duì)象中的invoke方法媳维。在invoke方法當(dāng)中首先驗(yàn)證了方法是否是Object的方法酿雪,如果是,就直接調(diào)用并返回了侄刽。然后判斷方法是否是默認(rèn)方法指黎,如果是,也直接返回了唠梨。那么重點(diǎn)就在最后四行代碼當(dāng)中了袋励。
loadServiceMehod方法分析
在create方法的倒數(shù)第四行調(diào)用了Retrofit的loadServiceMethod方法,該方法傳入method參數(shù)返回了一個(gè)ServiceMethod對(duì)象当叭。下面是loadServiceMethod方法的源碼
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;
}
這個(gè)方法也很簡(jiǎn)單茬故,首先判斷緩存當(dāng)中有沒有method對(duì)應(yīng)的ServiceMethod對(duì)象,如果有就返回該對(duì)象蚁鳖,沒有就創(chuàng)建對(duì)象并將其放入緩存磺芭。在構(gòu)建ServiceMethod對(duì)象時(shí)傳入了retrofit對(duì)象和method對(duì)象。
創(chuàng)建OkHttpCall對(duì)象
OkHttpCall(ServiceMethod<T, ?> serviceMethod, @Nullable Object[] args) {
this.serviceMethod = serviceMethod;
this.args = args;
}
OkHttpCall對(duì)象的構(gòu)造方法很簡(jiǎn)單醉箕,僅僅是對(duì)兩個(gè)屬性賦值而已钾腺。到目前為止還沒有看到一行關(guān)于網(wǎng)絡(luò)請(qǐng)求的代碼,那么網(wǎng)絡(luò)請(qǐng)求的代碼應(yīng)該是在create方法最后一行當(dāng)中了讥裤。
CallAdapter的adapt方法
在Retrofit的create方法最后一行調(diào)用了ServiceMethod的callAdapter的adapt方法放棒。ServiceMethod的CallAdapter對(duì)象是通過Retrofit中設(shè)置的CallAdapterFactoty對(duì)象創(chuàng)建出來的,我設(shè)置的是RxJava2CallAdapterFactory己英,那主要的網(wǎng)絡(luò)請(qǐng)求邏輯應(yīng)該是在RxJava2CallAdapterFactory里面了间螟。
RxJava2CallAdapterFactory的get方法
@Override
public CallAdapter<?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
Class<?> rawType = getRawType(returnType);
if (rawType == Completable.class) {
// Completable is not parameterized (which is what the rest of this method deals with) so it
// can only be created with a single configuration.
return new RxJava2CallAdapter(Void.class, scheduler, false, true, false, false, false, true);
}
boolean isFlowable = rawType == Flowable.class;
boolean isSingle = rawType == Single.class;
boolean isMaybe = rawType == Maybe.class;
if (rawType != Observable.class && !isFlowable && !isSingle && !isMaybe) {
return null;
}
boolean isResult = false;
boolean isBody = false;
Type responseType;
if (!(returnType instanceof ParameterizedType)) {
String name = isFlowable ? "Flowable" : isSingle ? "Single" : "Observable";
throw new IllegalStateException(name + " return type must be parameterized"
+ " as " + name + "<Foo> or " + name + "<? extends Foo>");
}
Type observableType = getParameterUpperBound(0, (ParameterizedType) returnType);
Class<?> rawObservableType = getRawType(observableType);
if (rawObservableType == Response.class) {
if (!(observableType instanceof ParameterizedType)) {
throw new IllegalStateException("Response must be parameterized"
+ " as Response<Foo> or Response<? extends Foo>");
}
responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
} else if (rawObservableType == Result.class) {
if (!(observableType instanceof ParameterizedType)) {
throw new IllegalStateException("Result must be parameterized"
+ " as Result<Foo> or Result<? extends Foo>");
}
responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
isResult = true;
} else {
responseType = observableType;
isBody = true;
}
return new RxJava2CallAdapter(responseType, scheduler, isResult, isBody, isFlowable,
isSingle, isMaybe, false);
}
該方法返回一個(gè)CallAdapter對(duì)象,也就是ServiceMethod中的CallAdapter對(duì)象损肛。首先分析一下該對(duì)象的創(chuàng)建過程厢破。該方法首先判斷我們調(diào)用的接口方法的返回值類型,返回值類型必須是Completable治拿,Observable摩泪,F(xiàn)lowable,Single劫谅,Maybe中的一種见坑,否則會(huì)返回null嚷掠。判斷完返回類型接著判斷返回類型的泛型,最后返回一個(gè)RxJava2CallAdapter對(duì)象鳄梅。
RxJava2CallAdapter的adapt方法
@Override public <R> Object adapt(Call<R> call) {
Observable<Response<R>> responseObservable = new CallObservable<>(call);
Observable<?> observable;
if (isResult) {
observable = new ResultObservable<>(responseObservable);
} else if (isBody) {
observable = new BodyObservable<>(responseObservable);
} else {
observable = responseObservable;
}
if (scheduler != null) {
observable = observable.subscribeOn(scheduler);
}
if (isFlowable) {
return observable.toFlowable(BackpressureStrategy.LATEST);
}
if (isSingle) {
return observable.singleOrError();
}
if (isMaybe) {
return observable.singleElement();
}
if (isCompletable) {
return observable.ignoreElements();
}
return observable;
}
這個(gè)方法主要根據(jù)接口方法返回值的類型和泛型類型返回不同的Observable叠国,如果返回值泛型是Result類型,返回ResultObservable戴尸,如果是返回值泛型是Response類型粟焊,返回responseObservable,如果是自定義的類型則返回BodyObservable孙蒙。到目前為止還是沒有發(fā)現(xiàn)網(wǎng)絡(luò)請(qǐng)求相關(guān)的代碼项棠,那么網(wǎng)絡(luò)請(qǐng)求的代碼應(yīng)該是在Observable里面了。平時(shí)請(qǐng)求一般都是自定義類型挎峦,那么主要看一下Observable當(dāng)中的邏輯香追。
CallObservable
final class CallObservable<T> extends Observable<Response<T>> {
private final Call<T> originalCall;
CallObservable(Call<T> originalCall) {
this.originalCall = originalCall;
}
@Override protected void subscribeActual(Observer<? super Response<T>> observer) {
// Since Call is a one-shot type, clone it for each new observer.
Call<T> call = originalCall.clone();
observer.onSubscribe(new CallDisposable(call));
boolean terminated = false;
try {
Response<T> response = call.execute();
if (!call.isCanceled()) {
observer.onNext(response);
}
if (!call.isCanceled()) {
terminated = true;
observer.onComplete();
}
} catch (Throwable t) {
Exceptions.throwIfFatal(t);
if (terminated) {
RxJavaPlugins.onError(t);
} else if (!call.isCanceled()) {
try {
observer.onError(t);
} catch (Throwable inner) {
Exceptions.throwIfFatal(inner);
RxJavaPlugins.onError(new CompositeException(t, inner));
}
}
}
}
private static final class CallDisposable implements Disposable {
private final Call<?> call;
CallDisposable(Call<?> call) {
this.call = call;
}
@Override public void dispose() {
call.cancel();
}
@Override public boolean isDisposed() {
return call.isCanceled();
}
}
}
CallObservable中有一個(gè)Call對(duì)象的引用,這個(gè)對(duì)象就是在Retrofit的create方法當(dāng)中的 OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args)這個(gè)okHttpCall對(duì)象坦胶。在CallObservable的subscribeActual方法當(dāng)中執(zhí)行了call.execute()透典,這行代碼返回了一個(gè)Response(注:這個(gè)Response類是Retrofit包當(dāng)中的,并非OkHttp當(dāng)中的)對(duì)象顿苇,那網(wǎng)絡(luò)請(qǐng)求的代碼應(yīng)該是在這個(gè)方法中執(zhí)行峭咒。
OkHttpCall的execute方法
@Override public Response<T> execute() throws IOException {
okhttp3.Call call;
synchronized (this) {
if (executed) throw new IllegalStateException("Already executed.");
executed = true;
if (creationFailure != null) {
if (creationFailure instanceof IOException) {
throw (IOException) creationFailure;
} else {
throw (RuntimeException) creationFailure;
}
}
call = rawCall;
if (call == null) {
try {
call = rawCall = createRawCall();
} catch (IOException | RuntimeException e) {
creationFailure = e;
throw e;
}
}
}
if (canceled) {
call.cancel();
}
return parseResponse(call.execute());
}
這個(gè)方法的邏輯很簡(jiǎn)單,首先創(chuàng)建一個(gè)okhttp3.Call對(duì)象纪岁,然后執(zhí)行call.execute方法凑队,最后將okhttp當(dāng)中的Response類型轉(zhuǎn)換為Retrofit當(dāng)中的Response對(duì)象。
OkHttpCall的parseResponse方法
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
ResponseBody rawBody = rawResponse.body();
// Remove the body's source (the only stateful object) so we can pass the response along.
rawResponse = rawResponse.newBuilder()
.body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
.build();
int code = rawResponse.code();
if (code < 200 || code >= 300) {
try {
// Buffer the entire body to avoid future I/O.
ResponseBody bufferedBody = Utils.buffer(rawBody);
return Response.error(bufferedBody, rawResponse);
} finally {
rawBody.close();
}
}
if (code == 204 || code == 205) {
rawBody.close();
return Response.success(null, rawResponse);
}
ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);
try {
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;
}
}
這個(gè)方法的主要邏輯就是根據(jù)不同的http響應(yīng)碼返回不同的Retrofit.Response幔翰。如果是正常的200響應(yīng)碼漩氨,會(huì)走最后這個(gè)return語(yǔ)句。返回一個(gè)Retrofit.Response對(duì)象,該對(duì)象封裝了一個(gè)泛型類型的body和一個(gè)OkHttp.Response對(duì)象遗增,這個(gè)泛型對(duì)象時(shí)通過ServiceMethod的toResponse方法返回的叫惊,在toResponse方法當(dāng)中會(huì)調(diào)用Converter的convert方法,也就是在創(chuàng)建Retrofit的時(shí)候設(shè)置的ConvertFactory創(chuàng)建出來的Convert做修,通常是設(shè)置GsonConvert,也就是將網(wǎng)絡(luò)請(qǐng)求的響應(yīng)體解析成接口方法泛型里面的類型霍狰。
BodyObservable
final class BodyObservable<T> extends Observable<T> {
private final Observable<Response<T>> upstream;
BodyObservable(Observable<Response<T>> upstream) {
this.upstream = upstream;
}
@Override protected void subscribeActual(Observer<? super T> observer) {
upstream.subscribe(new BodyObserver<>(observer));
}
private static class BodyObserver<R> implements Observer<Response<R>> {
private final Observer<? super R> observer;
private boolean terminated;
BodyObserver(Observer<? super R> observer) {
this.observer = observer;
}
@Override public void onSubscribe(Disposable disposable) {
observer.onSubscribe(disposable);
}
@Override public void onNext(Response<R> response) {
if (response.isSuccessful()) {
observer.onNext(response.body());
} else {
terminated = true;
Throwable t = new HttpException(response);
try {
observer.onError(t);
} catch (Throwable inner) {
Exceptions.throwIfFatal(inner);
RxJavaPlugins.onError(new CompositeException(t, inner));
}
}
}
@Override public void onComplete() {
if (!terminated) {
observer.onComplete();
}
}
@Override public void onError(Throwable throwable) {
if (!terminated) {
observer.onError(throwable);
} else {
// This should never happen! onNext handles and forwards errors automatically.
Throwable broken = new AssertionError(
"This should never happen! Report as a bug with the full stacktrace.");
//noinspection UnnecessaryInitCause Two-arg AssertionError constructor is 1.7+ only.
broken.initCause(throwable);
RxJavaPlugins.onError(broken);
}
}
}
}
前面這些網(wǎng)絡(luò)請(qǐng)求,響應(yīng)解析功能都是在CallObservable當(dāng)中完成的缓待,但最終返回給我們用的卻是BodyObservable蚓耽,BodyObservable對(duì)CallObservable做了一次封裝渠牲,onNext只傳了Retrofit.Response的body對(duì)象旋炒,也就時(shí)Gson解析出來的對(duì)象。這樣就只能得到響應(yīng)體签杈,某些時(shí)候需要用到響應(yīng)頭瘫镇,可以將接口方法的返回值的泛型使用Retrofit.Response就可以了鼎兽。
總結(jié)
1.創(chuàng)建Retrofit對(duì)象。
2.調(diào)用Retrofit對(duì)象的create方法返回動(dòng)態(tài)代理對(duì)象铣除。
3.調(diào)用動(dòng)態(tài)代理對(duì)象的方法谚咬。
4.調(diào)用CallAdapter的adapt方法,返回一個(gè)Observable對(duì)象尚粘。
5.在Observable對(duì)象subscribe方法當(dāng)中進(jìn)行網(wǎng)絡(luò)請(qǐng)求和響應(yīng)體的解析择卦。
(注:省略了根據(jù)接口方法注解生成Request部分)