retrofit2.4.0结合adapter-rxjava,converter-gson,源码解析

retrofit2.4结合adapter-rxjava,converter-gson,源码解析

Retrofit作为时下android里比较常用的库,特别是结合着rxjava 后用起来很是酸爽啊,本篇就是剖析一下retrofit2.0结合adapter-rxjava,converter-gson后整个流程是怎样串起来的,以及源码的解析

先看下retrofit简介

retrofit基本使用这里不再赘述,直奔主题直接看源码了

retrofit源码地址 图一就是今天的重点了,图二是发起请求对应的注解种类了

都知道retrofit实际调用的是okhttp。也可以说retrofi就是在okhttp的基础上包了一层,通过大量的设计模式进行功能模块的解耦,使得整个整个流程变得整洁和清爽、

接口

阅读一个三方库 先从接口入手,先了解一下上层大致提供了哪些功能有助于快速理解

**Call **

对于okhttp 的call的的一个再包装,也是真正发出请求的对象接口
public interface Call<T> extends Cloneable {

  Response<T> execute() throws IOException;

  void enqueue(Callback<T> callback);

  boolean isExecuted();

  void cancel();

  Call<T> clone();

  /**返回的是okhttp的Request. */
  Request request();
}
复制代码

**CallAdapter **

//可以把Call对象转化为另外一个对象,如Observable,Flowable
public interface CallAdapter<R, T> {
    //Type  返回值泛型的对象类型如:Flowable<Response<Bean>>里的Response<Bean>
    Type responseType();
    
   //传入一个R返回一个T,T:返回值 一个Call或者Flowable
    T adapt(Call<R> call);
//工厂里提供三个方法 1:根据返回值returnType获取具体请求的CallAdapter 2:根据返回值type 获取泛型里的数据类型
// 3:通过type获取class的类型,获取整个返回值的类型  如Observable<T>,Flowable<T> ,Call<T> 
// 2,3 均为工具类
    abstract class Factory {
//abstract抽象方法,一定要被实现
 public abstract @Nullable  CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit);
 
 protected static Type getParameterUpperBound(int index, ParameterizedType type) {
  return Utils.getParameterUpperBound(index, type);  
     
 }

 protected static Class<?> getRawType(Type type) {
 return Utils.getRawType(type);
  }
    }
}

**Callback **
请求回调
**Converter **
数据转换适配器,可以对请求的数据或者响应的数据再度处理
public interface Converter<F, T> {
  T convert(F value) throws IOException;

  /** Creates {@link Converter} instances based on a type and target usage. */
  abstract class Factory {
    /**
     * 传入ResponseBody返回t,对响应数据进行解析,converter-gson会重写此方法
     */
    public @Nullable Converter<ResponseBody, ?> responseBodyConverter(Type type,
        Annotation[] annotations, Retrofit retrofit) {
      return null;
    }

    /**
     *
     *传入T返回ResponseBody 对请求数据进行处理,只有在 申明@Body, @Part ,@PartMap
     *这三个注解时才会生效
     *
     */
    public @Nullable Converter<?, RequestBody> requestBodyConverter(Type type,
        Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
      return null;
    }

    /**     * 
     *  {@link Field @Field}, {@link FieldMap @FieldMap} values,
     * {@link Header @Header}, {@link HeaderMap @HeaderMap}, {@link Path @Path},
     * {@link Query @Query}, and {@link QueryMap @QueryMap} values.
     对以上注解的值进行处理 而已已经被BuiltInConverters(默认解析类)类重写,外部重写无效
     */
    public @Nullable Converter<?, String> stringConverter(Type type, Annotation[] annotations,
        Retrofit retrofit) {
      return null;
    }

    /**
   工具类作用与CallAdapter里的一样
     */
    protected static Type getParameterUpperBound(int index, ParameterizedType type) {
      return Utils.getParameterUpperBound(index, type);
    }
    
    protected static Class<?> getRawType(Type type) {
      return Utils.getRawType(type);
    }
  }
}

复制代码

基本使用

获取 retrofit 实例以及添加上rxjava 请求适配器和converter-gson解析器
    public Retrofit getRetrofit(String baseurl, OkHttpClient client) {
        if (client == null)
            client = getOkHttpClient();
        Retrofit.Builder builder = new Retrofit.Builder();
        builder.baseUrl(baseurl);//baseurl路径
        builder.client(client)//添加客户端
                .addConverterFactory(GsonConverterFactory.create());//添加Gson格式化工厂
            //添加 rxjava
            builder.addCallAdapterFactory(RxJava2CallAdapterFactory
                    .createWithScheduler(Schedulers.from(AppExecutor.instance())));
      
        retrofit = builder.build();
        return retrofit;
    }
    //自定义的通用解析类,t为data内具体对象,msg和code为公用数据部分
   public class Response<T> {
    private T data;
    private String msg;
    private String code;
       
   } 
//定义接口类
public interface ApiService {
     /**
     * 测试数据
     */
    @GET("data/福利/{num}/{page}")
    Flowable<Response<Bean>> getGirlList(@Path("num") int num, @Path("page") int page);   
}

//获取ApiService
ApiService  apiservice=getRetrofit(baseurl,OkHttpClient).create(serviceClass)

//发起请求,(这里未经封装,正常使用要再封装下)
apiservice.getGirlList(1,2).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribeWith(new ResourceSubscriber<Response<Bean>>() {
                @Override
                public void onNext(Response<Bean> o) {
                    //结果回调
                }

                @Override
                public void onError(Throwable t) {

                }

                @Override
                public void onComplete() {

                }
            })

复制代码

源码分析

Retrofit实例是使用建造者模式通过Builder类进行创建的

核心类
这里只关心Android平台下的java8的不看
    static class Android extends Platform {
        // Guarded by API check.
        @Override
        boolean isDefaultMethod(Method method) {
            if (Build.VERSION.SDK_INT < 24) {
                return false;
            }
            return method.isDefault();
        }

        @Override
        public Executor defaultCallbackExecutor() {
            return new MainThreadExecutor();
        }
        /**
         * ExecutorCallAdapterFactory默认工厂类,
         * if (getRawType(returnType) != Call.class) {
          * return null;}
          *只解析返回类型为Call.class的数据,即原生retrofit的返回值都会使用这个工厂,原因后面
         */
        @Override
        List<? extends CallAdapter.Factory> defaultCallAdapterFactories(
                @Nullable Executor callbackExecutor) {
            if (callbackExecutor == null) throw new AssertionError();
            return singletonList(new ExecutorCallAdapterFactory(callbackExecutor));
        }

        /**
         * android平台 默认为MainThreadExecutor,
         */
        static class MainThreadExecutor implements Executor {
            private final Handler handler = new Handler(Looper.getMainLooper());

            @Override
            public void execute(Runnable r) {
                handler.post(r);
            }
        }
    }
    
**默认CallAdapter实体类 提供了只解析解析返回Call.class类型的CallAdapter **
final class ExecutorCallAdapterFactory extends CallAdapter.Factory {
  final Executor callbackExecutor;

  ExecutorCallAdapterFactory(Executor callbackExecutor) {
    this.callbackExecutor = callbackExecutor;
  }

  @Override public @Nullable CallAdapter<?, ?> get(
      Type returnType, Annotation[] annotations, Retrofit retrofit) {
   if (getRawType(returnType) != Call.class) {
      return null;
    }
    final Type responseType = Utils.getCallResponseType(returnType);
    return new CallAdapter<Object, Call<?>>() {
      @Override public Type responseType() {
        return responseType;
      }

      @Override public Call<Object> adapt(Call<Object> call) {
        return new ExecutorCallbackCall<>(callbackExecutor, call);
      }
    };
  }


        public Retrofit build() {
            if (baseUrl == null) {
                throw new IllegalStateException("Base URL required.");
            }
            okhttp3.Call.Factory callFactory = this.callFactory;
            if (callFactory == null) {
                callFactory = new OkHttpClient();
            }
            Executor callbackExecutor = this.callbackExecutor;
            if (callbackExecutor == null) {
                //android平台下 默认为MainThreadExecutor,数据切换到主线程,okhttp默认是在子线程
                callbackExecutor = platform.defaultCallbackExecutor();
            }
            // Make a defensive copy of the adapters and add the default Call adapter.
            List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
            // 默认为 ExecutorCallAdapterFactory,只解析返回类型为Call.class的数据,即原生retrofit的返回值
            callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));

            // Make a defensive copy of the converters.
            List<Converter.Factory> converterFactories = new ArrayList<>(
                    1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());

            converterFactories.add(new BuiltInConverters());//默认数据解析类 
            当返回类型为ResponseBody时适用(即:原生okhttp)
            converterFactories.addAll(this.converterFactories);
            converterFactories.addAll(platform.defaultConverterFactories());;//defaultConverterFactories实际上什么也没有,默认的解析行为都在BuiltInConverters类
            //unmodifiableList() :返回一个只能被访问不能被修改的集合
            return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
                    unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
        }
       
复制代码

然后看下 GsonConverterFactory gson解析类 重写了responseBodyConverter和requestBodyConverter 实际都通过 gson 把返回数据或者请求数据解析成指定的type

public final class GsonConverterFactory extends Converter.Factory {
 /**
  * Create an instance using a default {@link Gson} instance for conversion. Encoding to JSON and
  * decoding from JSON (when no charset is specified by a header) will use UTF-8.
  */
 public static GsonConverterFactory create() {
   return create(new Gson());
 }

 /**
  * Create an instance using {@code gson} for conversion. Encoding to JSON and
  * decoding from JSON (when no charset is specified by a header) will use UTF-8.
  */
 public static GsonConverterFactory create(Gson gson) {
   return new GsonConverterFactory(gson);
 }

 private final Gson gson;

 private GsonConverterFactory(Gson gson) {
   if (gson == null) throw new NullPointerException("gson == null");
   this.gson = gson;
 }

 @Override
 public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
     Retrofit retrofit) {
   TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
   return new GsonResponseBodyConverter<>(gson, adapter);
 }

 @Override
 public Converter<?, RequestBody> requestBodyConverter(Type type,
     Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
   TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
   return new GsonRequestBodyConverter<>(gson, adapter);
 }
}
复制代码

**然后看下 RxJava2CallAdapterFactory rxjava适配器 实现get方法 只解析 返回类型为 Observable.class ,isFlowable , isSingle ,isMaybe四类

 public final class RxJava2CallAdapterFactory extends CallAdapter.Factory {
  /**
   * Returns an instance which creates synchronous observables that do not operate on any scheduler
   * by default.
   */
  public static RxJava2CallAdapterFactory create() {
    return new RxJava2CallAdapterFactory(null, false);
  }

  /**
   * Returns an instance which creates asynchronous observables. Applying
   * {@link Observable#subscribeOn} has no effect on stream types created by this factory.
   */
  public static RxJava2CallAdapterFactory createAsync() {
    return new RxJava2CallAdapterFactory(null, true);
  }

  /**
   * Returns an instance which creates synchronous observables that
   * {@linkplain Observable#subscribeOn(Scheduler) subscribe on} {@code scheduler} by default.
   */
  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;
  }

  @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, isAsync, 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"
          : isMaybe ? "Maybe" : "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, isAsync, isResult, isBody, isFlowable,
        isSingle, isMaybe, false);
  }
}
复制代码

**继续 Retrofit 类核心方法 **

    public <T> T create(final Class<T> service) {
        Utils.validateServiceInterface(service);//service必须为接口类,且方法数>0
        if (validateEagerly) {//validateEagerly  是否预解析service里所有方法注解,正常是使用一个方法才解析一个,然后放到缓存里,下次直接用缓存
            eagerlyValidateMethods(service);
        }
        //动态代理,传入一个接口返回一个对象
        return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[]{service},
                new InvocationHandler() {
                    private final Platform platform = Platform.get();
                    private final Object[] emptyArgs = new Object[0];

                    @Override
                    public Object invoke(Object proxy, Method method, @Nullable 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);
                        }
                        //platform.isDefaultMethod(method) 平台下 痕为fasle,兼容java8的不关心
                        if (platform.isDefaultMethod(method)) {
                            return platform.invokeDefaultMethod(method, service, proxy, args);
                        }
                        return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
                    }
                });
    }
    
   终于到重点  loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
复制代码

**先看 loadServiceMethod(method) **

核心方法 result = ServiceMethod.parseAnnotations(this, method);
 
  static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
    RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);

    Type returnType = method.getGenericReturnType();
    if (Utils.hasUnresolvableType(returnType)) {
      throw methodError(method,
          "Method return type must not include a type variable or wildcard: %s", returnType);
    }
    if (returnType == void.class) {
      throw methodError(method, "Service methods cannot return void.");
    }

    return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
  }

先看一下RequestFactory 类  通过解析注解 提供  okhttp3.Request(真正的请求)  
final class RequestFactory {
    static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
        return new Builder(retrofit, method).build();
    }
    private final Method method;  // 调用的service内方法名字
    private final HttpUrl baseUrl;
    final String httpMethod;   // 请求方法:get.post.put...
    private final String relativeUrl;//实际的url: baseUrl+ 后缀默认
    private final Headers headers;// 头信息
    private final MediaType contentType;//contentType
    private final boolean hasBody;// post方式才有
    private final boolean isFormEncoded;//是否是表单提交
    private final boolean isMultipart;//带文件的键值对提交
    private final ParameterHandler<?>[] parameterHandlers;//这个类很重要,负责根据不同的注解类型 去把传入的参数和注解的value 做相应的拼接处理
    
    
    //retrofit里关于注解的解析 都在Builder 里
       static final class Builder {
       Builder(Retrofit retrofit, Method method) {
            this.retrofit = retrofit;
            this.method = method;
            this.methodAnnotations = method.getAnnotations();//获取方法上的注解
            this.parameterTypes = method.getGenericParameterTypes();//传入参数对应的类型
            this.parameterAnnotationsArray = method.getParameterAnnotations();//参数注解,二维数组,每个参数上的注解都是数组
        }

        RequestFactory build() {
            for (Annotation annotation : methodAnnotations) {
               //确认请求方式 并对传入注解的value做校验,根据请求方式确定此次请求是否有body
                parseMethodAnnotation(annotation);
            }
               //这里开始解析方法上的注解参数,可以有多个参数然后 每个参数上可以跟多个注解,所有是个二维数组,说是这样说,但是实际操作的时候  一个参数上只允许跟一个注解,多了会包错
            int parameterCount = parameterAnnotationsArray.length;
            parameterHandlers = new ParameterHandler<?>[parameterCount];
            for (int p = 0; p < parameterCount; p++) {
                parameterHandlers[p] = parseParameter(p, parameterTypes[p], parameterAnnotationsArray[p]);
            }
            return new RequestFactory(this);
        }
  }    
    }
    
复制代码

**看下 parseParameter() **

  /**
         * 解析参数注解
         *
         * @param p 当前参数的位置
         * @param parameterType 参数对应的类型
         * @param annotations   参数对应的注解,retrofit只允许有一个
         * @return
         */
        private ParameterHandler<?> parseParameter(
                int p, Type parameterType, @Nullable Annotation[] annotations) {
            ParameterHandler<?> result = null;
            if (annotations != null) {
                for (Annotation annotation : annotations) {
                    ParameterHandler<?> annotationAction =
                            parseParameterAnnotation(p, parameterType, annotations, annotation);
                    if (annotationAction == null) {
                        continue;
                    }
                    //一个参数上只允许跟一个注解 多了会抛异常
                    if (result != null) {
                        throw parameterError(method, p,
                                "Multiple Retrofit annotations found, only one allowed.");
                    }
                    result = annotationAction;
                }
            }
            if (result == null) {
                throw parameterError(method, p, "No Retrofit annotation found.");
            }

            return result;
        }
        
复制代码

再看 parseParameterAnnotation()

转载于:https://juejin.im/post/5cc1233a5188252d9053cce7

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值