研究了兩個小時缠劝,終于讓我明白了Retrofit和RxJava是如何結合在一起的,分享給大家骗灶。本文將會從源碼角度來看這兩個家伙是如何配合的惨恭。閱讀前請確保理解Retrofit源碼和RxJava的基本使用。
支持原創(chuàng)耙旦,轉載請注明出處。
類圖
使用場景
//創(chuàng)建接口
public interface IShot {
//返回一個Observable锉罐,數(shù)據(jù)類型是List<Shot>
Observable<Response<List<Shot>>> getShot(@Query("page") int page);
}
//創(chuàng)建Retrofit
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(PeanutInfo.URL_BASE)
.addConverterFactory(GsonConverterFactory.create())//添加GsonConverter
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())//添加RxJavaCallAdapter
.build();
//創(chuàng)建代理對象
IShot server = retrofit.create(Shot.class);
//發(fā)送請求绕娘,返回Observable
Observable<Response<List<Shot>>> observable = server.getShot(1);
//傳入Subscribe,進行訂閱
observable.subscribe(new Subscribe....);
創(chuàng)建Observable
在創(chuàng)建Retrofit時我們添加了GsonConverter和RxJavaCallAdapter抖拦。我們回想下Retrofit源碼舷暮,在調用了代理對象的getShot方法后會調用MethodHandler的invoke方法:
Object invoke(Object... args) {
return callAdapter.adapt(
new OkHttpCall<>(callFactory, requestFactory, args, responseConverter));
}
這里的callAdpter是由RxJavaCallAdapterFactory返回的下面,因為我們指定了CallAdapterFactory為RxJavaCallAdapterFactory,我們看看RxJavaCallAdapterFactory的源碼沥割,這個類在retrofit2/adapter
包下:
public final class RxJavaCallAdapterFactory extends CallAdapter.Factory
---------------------------------get方法---------------------------------------------
@Override
public CallAdapter<?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
Class<?> rawType = getRawType(returnType); //獲取范型類型机杜,這里是Response<List<Shot>>
boolean isSingle = "rx.Single".equals(rawType.getCanonicalName());
if (rawType != Observable.class && !isSingle) {
return null;
}
if (!(returnType instanceof ParameterizedType)) {
String name = isSingle ? "Single" : "Observable";
throw new IllegalStateException(name + " return type must be parameterized"
+ " as " + name + "<Foo> or " + name + "<? extends Foo>");
}
CallAdapter<Observable<?>> callAdapter = getCallAdapter(returnType); //根據(jù)返回類型獲取CallAdapter
if (isSingle) {
// Add Single-converter wrapper from a separate class. This defers classloading such that
// regular Observable operation can be leveraged without relying on this unstable RxJava API.
return SingleHelper.makeSingle(callAdapter);
}
return callAdapter;
}
這個方法里根據(jù)返回類型returnType獲取范型類型rawType,我們這里是Response<List<Shot>>似将,然后根據(jù)rawType獲取CallAdapter,我們接著看下getCallAdapter方法:
private CallAdapter<Observable<?>> getCallAdapter(Type returnType) {
Type observableType = getParameterUpperBound(0, (ParameterizedType) returnType);
Class<?> rawObservableType = getRawType(observableType);
if (rawObservableType == Response.class) { //Response類型
if (!(observableType instanceof ParameterizedType)) {
throw new IllegalStateException("Response must be parameterized"
+ " as Response<Foo> or Response<? extends Foo>");
}
Type responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
return new ResponseCallAdapter(responseType); //返回ResponseCallAdapter
}
if (rawObservableType == Result.class) {
if (!(observableType instanceof ParameterizedType)) {
throw new IllegalStateException("Result must be parameterized"
+ " as Result<Foo> or Result<? extends Foo>");
}
Type responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
return new ResultCallAdapter(responseType); //返回ResultCallAdapter
}
return new SimpleCallAdapter(observableType); //返回SimpleCallAdapter
}
該方法根據(jù)返回值的具體類型返回對應的CallAdapter玷氏,我們的類型是Response<List<Shot>>,對應Response類盏触,所以返回ResponseCallAdapter块饺,終于找到了CallAdapter類了。再來回顧下MethodHandler的invoke方法:
Object invoke(Object... args) {
return callAdapter.adapt(
new OkHttpCall<>(callFactory, requestFactory, args, responseConverter));
}
我們看下ResponseCallAdapter的adapt()方法:
static final class ResponseCallAdapter implements CallAdapter<Observable<?>> {
private final Type responseType;
ResponseCallAdapter(Type responseType) {
this.responseType = responseType;
}
@Override public Type responseType() {
return responseType;
}
@Override public <R> Observable<Response<R>> adapt(Call<R> call) {
return Observable.create(new CallOnSubscribe<>(call)); //創(chuàng)建一個CallOnSubscribe诗宣,用這個CallOnSubscribe創(chuàng)建Observable想诅,并返回。
}
}
到這里終于創(chuàng)建好了Observable来破。我們看下CallOnSubscribe這個類:
static final class CallOnSubscribe<T> implements Observable.OnSubscribe<Response<T>> {
private final Call<T> originalCall; //引用OkHttpCall
CallOnSubscribe(Call<T> originalCall) {
this.originalCall = originalCall; //傳入的是OkHttpCall
}
@Override public void call(final Subscriber<? super Response<T>> subscriber) {
// Since Call is a one-shot type, clone it for each new subscriber.
final Call<T> call = originalCall.clone();
subscriber.add(Subscriptions.create(new Action0() {
@Override public void call() { //訂閱時調用這個方法
call.cancel();
}
}));
try {
Response<T> response = call.execute(); //執(zhí)行網絡請求
if (!subscriber.isUnsubscribed()) {
subscriber.onNext(response); //將結果傳入subscriber.onNext
}
} catch (Throwable t) {
Exceptions.throwIfFatal(t);
if (!subscriber.isUnsubscribed()) {
subscriber.onError(t); //出現(xiàn)錯誤是調用 subscriber.onError
}
return;
}
if (!subscriber.isUnsubscribed()) {
subscriber.onCompleted();
}
}
}
CallOnSubscribe實現(xiàn)了OnSubscribe接口诅诱,內部引用了OkHttpCall,執(zhí)行真正的網絡請求娘荡。進行訂閱時會調用call方法驶沼,該方法調用OkHttpCall.execute獲取響應,傳遞給subscriber.onNext這樣就發(fā)生了一次訂閱回怜。到這里Retrofit和RxJava就完美結合了。
最后看下類圖玉雾,就更清楚了。
總結
Retrofit添加了RxJavaCallAdapterFactory后垦缅,對應的callAdapter就是ResponseAdapter或SimpleCallAdapter類壁涎,他們的adapt方法返回一個Observable對象柏蘑,這個Observable內部引用了真正執(zhí)行網絡請求的OkHttpCall。
后面會將更多筆記整理成博客洽损,歡迎關注。
支持原創(chuàng)流码,轉載請注明出處。