美文网首页
Retrofit学习(二)

Retrofit学习(二)

作者: 王小宝wy | 来源:发表于2017-07-11 15:46 被阅读0次

之前的Retrofit学习(一)了解了一下Retrofit的最基本使用,不过目前最流行的Retrofit使用方式是Retrofit + RxJava + Gson, 如果要使用RxJava, 需要在创建Retrofit时配置RxJava对应的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提供了三个create系列方法,一般情况下,最常使用的是第一个没有参数的create方法,即不指定SchedulerisAsync = false, isAsync指明是调用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(...);
        }

        //获取返回值的泛型参数
        Type observableType = getParameterUpperBound(0, (ParameterizedType) returnType);
        Class<?> rawObservableType = getRawType(observableType);
        if (rawObservableType == Response.class) {
            //如果泛型参数是Response, 且Response没有泛型参数,抛出异常,Response必须是以泛型形式使用
            if (!(observableType instanceof ParameterizedType)) {
                throw new IllegalStateException(...);
            }
            //获取Response<T>中的T
            responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
        } else if (rawObservableType == Result.class) {
            //如果泛型参数是Result, 且Result没有泛型参数, 抛出异常,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, 直接返回一个RxJava2CallAdapter指定其中的isBody = true, isCompletable = true
  2. 确保方法的返回值Observable, Flowable, Single, Maybe, 否则返回null, 如果是null, 则根据之前的分析,如果CallAdapter.Factory.get()返回null, 在Retrofit.nextCallAdapter中会抛出异常(Retrofit默认有一个ExecutorCallAdapterFactory, 但如果方法返回值不是Call类型,其get()方法会直接返回null)
  3. 如果返回值不是泛型,抛出异常
  4. 获取返回值中的泛型参数的类型,假设返回值类型Observable<Bean>, 这里获取到的泛型参数类型就是Bean
  5. 如果泛型参数的类型是retrofit2.Responseretrofit2.Result,确保ResponseResult也是以泛型的形式声明的,即返回值类型是Observable<Response<T>>Observable<Result<T>>Retrofit + RxJava2最常见的的用法是Observable<Bean> getName(...), 一般都会直接使用自定义的Bean类, 所以一般情况下, isBody = true
  6. 返回RxJava2CallAdapter

RxJava2CallAdapter.adapt


    public Object adapt(Call<R> call) {
        //call是OkHttpCall, 将R转换为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>转换为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. 首先生成一个Obsersavle<Response<R>>, 这里会根据isAsync是否为tru,来确定是生成CallEnqueueObservable还是CallExecuteObservable,这两者的区别在于前者最终实际是调用OkHttpCall.enqueue方法,后者实际调用了OkHttpCall.execute方法, 前者异步执行,后者同步执行
  2. Retrofit + RxJava2最常见的的用法是Observable<Bean> getName(...), 一般都会直接使用自定义的Bean类,
  3. 根据之前的分析可以知道,一般情况下,由于开发者都直接使用自己的Bean, 所以isBody = true, 会创建一个BodyObservable
  4. 之后会根据方法返回值是否是Flowable, Single, Maybe, Completable其中一种来做出具体的转换

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是一个代理
        //作用就是把Response<T>转换为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,一般情况下,这里会是CallExecutorObservable在subscribeActual中可以看到,在传入的observer外又包装了一个BodyObserver, 传入的observer就是开发者传入的自定义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会调用OkHttpCall.execute(), 从而得到okhttp3.Response
            //再从okhttp3.Response中得到okhttp3.ResponseBody, 然后调用    Converter.convert转换结果,最后将接过封装为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中会调用call.execute即调用OkHttpCall.execute来从而得到okhttp3.Response, 再从okhttp3.Response中得到okhttp3.ResponseBody, 然后调用 Converter.convert转换结果,最后将结果封装为retrofit.Response,

subscribeActual的参数observerBodyObserver, 而从之前的分析中可以看到BodyObserver的各方法会再调用开发人员自定义的Observer的响应方法

这里看似比较抽象的一系列操作,是为了获得一个统一的结果, 一般开发人员在定义请求方法时,都会使用Observable<Bean>这种方式,即直接将Observable<T>中的T设为自定义Bean, 但不同场景下肯定会定义不同的类型Bean, Retrofit不可能预先知道开发人员会定义那些Bean, 为了得到一个统一的结果,先将Bean转换为Reponse<T>,这样无论T是哪种类型,都可以得到一个统一的结果,之后再通过Response.body()将Response转换为自定义Bean

相关文章

网友评论

      本文标题:Retrofit学习(二)

      本文链接:https://www.haomeiwen.com/subject/rmrmhxtx.html