Retrofit2.0的使用之自定义CallAdapter.Factory

上一篇说到自定义Converter.Factory,那么很显然的在开发中我们也可能需要自定义CallAdapter,以实现我们的需求。例如:我们想要获取响应头信息进行某些操作,当然你可以你可以使用Response< T >或Result< T >作为响应实体类,但是如果我们这么写的话,那么在每个响应结果回调的地方都需要处理响应头,显然这是很麻烦的。因此,我们可以在CallAdapter里统一处理我们的响应头信息。

  1. 创建自定义的适配器工厂继承自CallAdapter.Factory;
  2. 创建自定义的适配器继承自CallAdapter< T >;
  3. 创建自定义的回调处理类CustomCall< R >。

一、创建适配器工厂

class MyCallAdapterFactory extends CallAdapter.Factory {
    //这里写步骤2、3的内容和一些必要的初始化 参考RxJavaCallAdapter

 //这个决定了你将采取什么样的CallAdapter
 @Override
 public CallAdapter get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
        //获取returnType的原始类型  如 CustomCall
        Class rawType = getRawType(returnType);
        //返回值的类型必须是CustomCall<>  并且带有泛型
        if (rawType == CustomCall.class && returnType instanceof ParameterizedType) {
            //获取returnType泛型的类型  如Call中的MovieDataBean
            Type callReturnType = getParameterUpperBound(0, (ParameterizedType) returnType);
            //使用CustomCallAdapter转换处理数据
            return new CustomCallAdapter(callReturnType);
        } else {
            return null;
        }
    }
}

代码中的注释已经比较清晰了,不做赘述;想了解更多的请参考RxJavaCallAdapter的源码。上面代码,提到了new CustomCallAdapter(callReturnType)这就是我们的自定义CallAdapter了,下面来一段示例代码意思一下。

二、自定义的CallAdapter

/**
*其实这个类也是啥也没写 最终还是由CustomCall完成的
*/
 class CustomCallAdapter implements CallAdapter> {

        private final Type responseType;

        // 下面的 responseType 方法需要数据的类型
        CustomCallAdapter(Type responseType) {
            this.responseType = responseType;
        }

        @Override
        public Type responseType() {
            return responseType;
        }

        @Override
        public  CustomCall adapt(Call call) {
            //由我们自定义的CustomCall<> 处理数据
            return new CustomCall<>(call);
        }
    }

CustomCall< R > 才是真正处理数据的类

//这个类只做一个大致流程的实例 没有什么实际意义
class CustomCall {
        public final Call call;
        public CustomCall(Call call) {
            this.call = call;
        }
        // 提供一个同步获取数据的方法
        public R get() throws IOException {
            return call.execute().body();
        }
    }

这个自定义就差不多了。

下面再来一个参考RxJavaCallAdapter创建的一个CallAdapterFactory:

public final class MyRxCallAdapter extends CallAdapter.Factory 
    public static MyRxCallAdapter create() {
        return new MyRxCallAdapter(null);
    }

    public static MyRxCallAdapter createWithScheduler(Scheduler scheduler) {
        if (scheduler == null) throw new NullPointerException("scheduler == null");
        return new MyRxCallAdapter(scheduler);
    }

    private final Scheduler scheduler;

    private MyRxCallAdapter(Scheduler scheduler) {
        this.scheduler = scheduler;
    }

    //获取不同的CallAdapter
    @Override
    public CallAdapter get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
        //获取returnType的原始类型
        Class rawType = getRawType(returnType);
        //获取类名
        String canonicalName = rawType.getCanonicalName();
        //是否是以下两种类型
        boolean isSingle = "rx.Single".equals(canonicalName);
        boolean isCompletable = "rx.Completable".equals(canonicalName);
        if (rawType != Observable.class && !isSingle && !isCompletable) {
            return null;
        }
        if (!isCompletable && !(returnType instanceof ParameterizedType)) {
            String name = isSingle ? "Single" : "Observable";
            throw new IllegalStateException(name + " return type must be parameterized"
                    + " as " + name + " or " + name + "");
        }

        if (isCompletable) {
            // Add Completable-converter wrapper from a separate class. This defers classloading such that
            // regular Observable operation can be leveraged without relying on this unstable RxJava API.
            // Note that this has to be done separately since Completable doesn't have a parametrized
            // type.

//            return CompletableHelper.createCallAdapter(scheduler);
        }

        CallAdapter> callAdapter = getCallAdapter(returnType, scheduler);
        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;
    }

    private CallAdapter> getCallAdapter(Type returnType, Scheduler scheduler) {
        //获取returnType的 泛型参数类型  ParameterizedType-->>泛型
        Type observableType = getParameterUpperBound(0, (ParameterizedType) returnType);
        //获取observableType的原始类的类型
        Class rawObservableType = getRawType(observableType);
        //返回值是Response 使用ResponseCallAdapter
        //我们使用Response 作为返回类型  Observable>
        //Response 把Headers、code等一些响应数据放到response里一起返回到我们的回调里(xxSubscriber)
        if (rawObservableType == Response.class) {
            //毋庸置疑 必须是泛型类型
            if (!(observableType instanceof ParameterizedType)) {
                throw new IllegalStateException("Response must be parameterized"
                        + " as Response or Response");
            }
            //获取observableType的泛型参数的类型
            Type responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
            return new ResponseCallAdapter(responseType, scheduler);
        }

        //返回值是 Result 使用ResultCallAdapter
        //我们使用Result 作为返回类型 Observable>
        //Result 包含了Response中的所有信息,额外还有error信息
        if (rawObservableType == Result.class) {
            if (!(observableType instanceof ParameterizedType)) {
                throw new IllegalStateException("Result must be parameterized"
                        + " as Result or Result");
            }
            Type responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
            return new ResultCallAdapter(responseType, scheduler);
        }

        //返回值是普通的Object 使用SimpleCallAdapter  Observable、Observable>....
        //(我们的自定义CallAdapter)其实在SimpleCallAdapter中 还是将Response>转换成了HttpResult 在我们的回调里移除了Response包含的信息
        //在原RxJavaCallAdapter中使用 OperatorMapResponseToBodyOrError 把原Response 转换成我们自己声明的类型或错误异常类型
        return new SimpleCallAdapter(observableType, scheduler);
    }

    //结果回调  在这里定义了回调流程 onNext() onError()(如果有异常则 onError() 然后return) onComplete();
    static final class CallOnSubscribe implements Observable.OnSubscribe> {
        private final Call originalCall;

        CallOnSubscribe(Call originalCall) {
            this.originalCall = originalCall;
        }

        @Override
        public void call(final Subscribersuper Response> subscriber) {
            // Since Call is a one-shot type, clone it for each new subscriber.
            final Call call = originalCall.clone();

            // Attempt to cancel the call if it is still in-flight on unsubscription.
            subscriber.add(Subscriptions.create(new Action0() {
                @Override
                public void call() {
                    call.cancel();
                }
            }));

            try {
                Response response = call.execute();
                if (!subscriber.isUnsubscribed()) {
                    subscriber.onNext(response);
                }
            } catch (Throwable t) {
                Exceptions.throwIfFatal(t);
                if (!subscriber.isUnsubscribed()) {
                    subscriber.onError(t);
                }
                return;
            }

            if (!subscriber.isUnsubscribed()) {
                subscriber.onCompleted();
            }
        }
    }

    static final class ResponseCallAdapter implements CallAdapter> {
        private final Type responseType;
        private final Scheduler scheduler;

        ResponseCallAdapter(Type responseType, Scheduler scheduler) {
            this.responseType = responseType;
            this.scheduler = scheduler;
        }

        @Override
        public Type responseType() {
            return responseType;
        }

        @Override
        public  Observable> adapt(Call call) {
            Observable> observable = Observable.create(new CallOnSubscribe<>(call));
            if (scheduler != null) {
                return observable.subscribeOn(scheduler);
            }
            return observable;
        }
    }

    static final class SimpleCallAdapter implements CallAdapter> {
        private final Type responseType;
        private final Scheduler scheduler;

        SimpleCallAdapter(Type responseType, Scheduler scheduler) {
            this.responseType = responseType;
            this.scheduler = scheduler;
        }

        @Override
        public Type responseType() {
            return responseType;
        }

        @Override
        public  Observable adapt(Call call) {
            Observable observable = Observable.create(new CallOnSubscribe<>(call))
                    .flatMap(new Func1, Observable>(){
                        @Override
                        public Observable call(Response rResponse) {
                            //在这里可以获取响应头信息统一处理处理你的逻辑
                            return null;
                        }
                    });
            if (scheduler != null) {
                return observable.subscribeOn(scheduler);
            }
            return observable;
        }
    }

    static final class ResultCallAdapter implements CallAdapter> {
        private final Type responseType;
        private final Scheduler scheduler;

        ResultCallAdapter(Type responseType, Scheduler scheduler) {
            this.responseType = responseType;
            this.scheduler = scheduler;
        }

        @Override
        public Type responseType() {
            return responseType;
        }

        @Override
        public  Observable> adapt(Call call) {
            Observable> observable = Observable.create(new CallOnSubscribe<>(call)) //
                    .map(new Func1, Result>() {
                        @Override
                        public Result call(Response response) {
                            return Result.response(response);
                        }
                    }).onErrorReturn(new Func1>() {
                        @Override
                        public Result call(Throwable throwable) {
                            return Result.error(throwable);
                        }
                    });
            if (scheduler != null) {
                return observable.subscribeOn(scheduler);
            }
            return observable;
        }
    }
}

代码中已经有了很多注释了,我也懒得讲了。这个地方我主要用的是SimpleCallAdapter。

你可能感兴趣的:(android学习笔记)