Retrofit學(xué)習(xí)(二)

之前的Retrofit學(xué)習(xí)(一)了解了一下Retrofit的最基本使用,不過目前最流行的Retrofit使用方式是Retrofit + RxJava + Gson, 如果要使用RxJava, 需要在創(chuàng)建Retrofit時(shí)配置RxJava對(duì)應(yīng)的CallAdapter:

    OkHttpclient client = new OkHttpClient.Builder().build();
    Retrofit retrofit = new Retrofit.Builder()
        .client(client)
        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
        .baseUrl("http://localhost:4567/")
        .build();

下面就主要分析一下RxJava2CallAdapterFactory是如何工作的

RxJava2CallAdapterFactory

    public static RxJava2CallAdapterFactory create() {
        return new RxJava2CallAdapterFactory(null, false);
    }
    
    public static RxJava2CallAdapterFactory createAsync() {
        return new RxJava2CallAdapterFactory(null, true);
    }
    
    public static RxJava2CallAdapterFactory createWithScheduler(Scheduler scheduler) {
        if (scheduler == null) throw new NullPointerException("scheduler == null");
        return new RxJava2CallAdapterFactory(scheduler, false);
    }
    
    private final Scheduler scheduler;
    private final boolean isAsync;
    
    private RxJava2CallAdapterFactory(Scheduler scheduler, boolean isAsync) {
        this.scheduler = scheduler;
        this.isAsync = isAsync;
    }

RxJava2CallAdapterFactory提供了三個(gè)create系列方法,一般情況下,最常使用的是第一個(gè)沒有參數(shù)的create方法,即不指定Scheduler,isAsync = false, isAsync指明是調(diào)用Call.execute還是Call.enqueue

RxJava2CallAdapterFactory.get


    public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
        Class<?> rawType = getRawType(returnType);

        if (rawType == Completable.class) {
            return new RxJava2CallAdapter(Void.class, scheduler, isAsync, false, true, false, false,
                    false, true);
        }

        boolean isFlowable = rawType == Flowable.class;
        boolean isSingle = rawType == Single.class;
        boolean isMaybe = rawType == Maybe.class;
        //確保返回值是Observable, Flowable, Single, Maybe
        if (rawType != Observable.class && !isFlowable && !isSingle && !isMaybe) {
            return null;
        }

        boolean isResult = false;
        boolean isBody = false;
        Type responseType;
        //ParameterizedType指泛型類型,如List<T>
        if (!(returnType instanceof ParameterizedType)) {
            String name = isFlowable ? "Flowable"
                    : isSingle ? "Single"
                    : isMaybe ? "Maybe" : "Observable";
            throw new IllegalStateException(...);
        }

        //獲取返回值的泛型參數(shù)
        Type observableType = getParameterUpperBound(0, (ParameterizedType) returnType);
        Class<?> rawObservableType = getRawType(observableType);
        if (rawObservableType == Response.class) {
            //如果泛型參數(shù)是Response, 且Response沒有泛型參數(shù),拋出異常,Response必須是以泛型形式使用
            if (!(observableType instanceof ParameterizedType)) {
                throw new IllegalStateException(...);
            }
            //獲取Response<T>中的T
            responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
        } else if (rawObservableType == Result.class) {
            //如果泛型參數(shù)是Result, 且Result沒有泛型參數(shù), 拋出異常,Result必須是以泛型形式使用
            if (!(observableType instanceof ParameterizedType)) {
                throw new IllegalStateException(...);
            }
            //獲取Result<T>中的T
            responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
            isResult = true;
        } else {
            responseType = observableType;
            isBody = true;
        }

        return new RxJava2CallAdapter(responseType, scheduler, isAsync, isResult, isBody, isFlowable,
                isSingle, isMaybe, false);
    }``

  1. 如果返回值類型是Completable, 直接返回一個(gè)RxJava2CallAdapter指定其中的isBody = true, isCompletable = true
  2. 確保方法的返回值Observable, Flowable, Single, Maybe, 否則返回null, 如果是null, 則根據(jù)之前的分析,如果CallAdapter.Factory.get()返回null, 在Retrofit.nextCallAdapter中會(huì)拋出異常(Retrofit默認(rèn)有一個(gè)ExecutorCallAdapterFactory, 但如果方法返回值不是Call類型,其get()方法會(huì)直接返回null)
  3. 如果返回值不是泛型,拋出異常
  4. 獲取返回值中的泛型參數(shù)的類型,假設(shè)返回值類型Observable<Bean>, 這里獲取到的泛型參數(shù)類型就是Bean
  5. 如果泛型參數(shù)的類型是retrofit2.Responseretrofit2.Result,確保ResponseResult也是以泛型的形式聲明的,即返回值類型是Observable<Response<T>>Observable<Result<T>>Retrofit + RxJava2最常見的的用法是Observable<Bean> getName(...), 一般都會(huì)直接使用自定義的Bean類, 所以一般情況下, isBody = true
  6. 返回RxJava2CallAdapter

RxJava2CallAdapter.adapt


    public Object adapt(Call<R> call) {
        //call是OkHttpCall, 將R轉(zhuǎn)換為Response<R>
        Observable<Response<R>> responseObservable = isAsync
                ? new CallEnqueueObservable<>(call)
                : new CallExecuteObservable<>(call);

        Observable<?> observable;
        if (isResult) {
            observable = new ResultObservable<>(responseObservable);
        } else if (isBody) {
            //將Response<T>轉(zhuǎn)換為T
            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;
    }
  1. 首先生成一個(gè)Obsersavle<Response<R>>, 這里會(huì)根據(jù)isAsync是否為tru,來確定是生成CallEnqueueObservable還是CallExecuteObservable,這兩者的區(qū)別在于前者最終實(shí)際是調(diào)用OkHttpCall.enqueue方法,后者實(shí)際調(diào)用了OkHttpCall.execute方法, 前者異步執(zhí)行,后者同步執(zhí)行
  2. Retrofit + RxJava2最常見的的用法是Observable<Bean> getName(...), 一般都會(huì)直接使用自定義的Bean類,
  3. 根據(jù)之前的分析可以知道,一般情況下,由于開發(fā)者都直接使用自己的Bean, 所以isBody = true, 會(huì)創(chuàng)建一個(gè)BodyObservable
  4. 之后會(huì)根據(jù)方法返回值是否是Flowable, Single, Maybe, Completable其中一種來做出具體的轉(zhuǎn)換

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是CallExecuteObservable或CallEnqueueObservable, BodyObserver是一個(gè)代理
        //作用就是把Response<T>轉(zhuǎn)換為T
        upstream.subscribe(new BodyObserver<T>(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 {
                ...
            }            }
        }

        @Override
        public void onComplete() {
            if (!terminated) {
                observer.onComplete();
            }
        }

        @Override
        public void onError(Throwable throwable) {
            if (!terminated) {
                observer.onError(throwable);
            } else {
                ...
            }
        }
    }
}

這里upstreamCallExecutorObservableCallEnqueueObservable,一般情況下,這里會(huì)是CallExecutorObservable;在subscribeActual中可以看到,在傳入的observer外又包裝了一個(gè)BodyObserver, 傳入的observer就是開發(fā)者傳入的自定義Observer

CallExecutorObservable

final class CallExecuteObservable<T> extends Observable<Response<T>> {
    private final Call<T> originalCall;

    CallExecuteObservable(Call<T> originalCall) {
        this.originalCall = originalCall;
    }

    @Override
    protected void subscribeActual(Observer<? super Response<T>> observer) {
        //originalCall是OkHttpCall
        Call<T> call = originalCall.clone();
        observer.onSubscribe(new CallDisposable(call));

        boolean terminated = false;
        try {
            //call.execute會(huì)調(diào)用OkHttpCall.execute(), 從而得到okhttp3.Response
            //再?gòu)膐khttp3.Response中得到okhttp3.ResponseBody, 然后調(diào)用    Converter.convert轉(zhuǎn)換結(jié)果,最后將接過封裝為retrofit.Response
            Response<T> response = call.execute();
            if (!call.isCanceled()) {
                //BodyObserver.onNext -> 自定義Onserver.onNext
                observer.onNext(response);
            }
            if (!call.isCanceled()) {
                terminated = true;
                observer.onComplete();
            }
        } catch (Throwable t) {
            ...
        }
    }

    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();
        }
    }
}

originalCallOkHttpCall, 可以看到在subscribeActual中會(huì)調(diào)用call.execute即調(diào)用OkHttpCall.execute來從而得到okhttp3.Response, 再?gòu)膐khttp3.Response中得到okhttp3.ResponseBody, 然后調(diào)用 Converter.convert轉(zhuǎn)換結(jié)果,最后將結(jié)果封裝為retrofit.Response,

subscribeActual的參數(shù)observerBodyObserver, 而從之前的分析中可以看到BodyObserver的各方法會(huì)再調(diào)用開發(fā)人員自定義的Observer的響應(yīng)方法

這里看似比較抽象的一系列操作,是為了獲得一個(gè)統(tǒng)一的結(jié)果, 一般開發(fā)人員在定義請(qǐng)求方法時(shí),都會(huì)使用Observable<Bean>這種方式,即直接將Observable<T>中的T設(shè)為自定義Bean, 但不同場(chǎng)景下肯定會(huì)定義不同的類型Bean, Retrofit不可能預(yù)先知道開發(fā)人員會(huì)定義那些Bean, 為了得到一個(gè)統(tǒng)一的結(jié)果,先將Bean轉(zhuǎn)換為Reponse<T>,這樣無論T是哪種類型,都可以得到一個(gè)統(tǒng)一的結(jié)果,之后再通過Response.body()將Response轉(zhuǎn)換為自定義Bean

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容