Retrofit 关于ConvertFactory的顺序执行记录

在配置Retrofit 的时候,有如下方法

 .addConverterFactory(GsonConverterFactory.create())
  .addConverterFactory(StringConverterFactory.create())

.addConverterFactory方法为添加相应结果解析器,存放于Retrofit.Builder类的converterFactories集合中。从Builder的构造方法可以看出创建Builder的时候会自动添加一个默认的ConvertFactory,我们也可以调用多次addConverterFactory添加多个ConvertFactory,处理结果的时候会按添加顺序优先匹配,一旦匹配上前面的,就丢弃后面的,当然我们能添加自己定义的ConvertFactory只要继承Converter.Factory,
在 Retrofit类中默认加了BuiltInConverters(593-603行),

  List<Converter.Factory> converterFactories =
          new ArrayList<>(1 + this.converterFactories.size());

      // Add the built-in converter factory first. This prevents overriding its behavior but also
      // ensures correct behavior when using converters that consume all types.
      converterFactories.add(new BuiltInConverters());
      converterFactories.addAll(this.converterFactories);

      return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
          unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);

在BuiltInConverters 中对ResponseBody和Void类型进行了转换处理

final class BuiltInConverters extends Converter.Factory {
  @Override
  public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
      Retrofit retrofit) {
    if (type == ResponseBody.class) {
      return Utils.isAnnotationPresent(annotations, Streaming.class)
          ? StreamingResponseBodyConverter.INSTANCE
          : BufferingResponseBodyConverter.INSTANCE;
    }
    if (type == Void.class) {
      return VoidResponseBodyConverter.INSTANCE;
    }
    return null;
  }
...

经过测试,当自定义ConverterFactory时,在 responseBodyConverter 方法中,return null,才会执行下一个解析器,抛出异常和进行处理,不会执行到下一个解析器
当使用GsonConverterFactory,后面的解析器不会执行(因为GsonConverterFactory能对任何数据都可以进行转换(最多转换异常嘛))
假如自定义StringConverterFactory,而且还想要执行GsonConverterFactory,必须这样写

 .addConverterFactory(StringConverterFactory.create())
 .addConverterFactory(GsonConverterFactory.create())

并且在StringConverterFactory的responseBodyConverter方法中进行处理

   @Override
    public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
        Log.e("StringConverter","action");
        if (type == String.class){
            return new StringConverter();
        }else{
//            throw new NullPointerException("type != String");
            return  null;
        }
//        return  null;
    }

下面是StringConverterFactory 代码

public final class StringConverterFactory extends Converter.Factory{

    public static StringConverterFactory create() {
        return new StringConverterFactory();
    }

    @Override
    public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
        Log.e("StringConverter","action");
        if (type == String.class){
            return new StringConverter();
        }else{
//            throw new NullPointerException("type != String");
            return  null;
        }
//        return  null;
    }

    @Nullable
    @Override
    public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
        return new StringRequestBodyConverter();
    }
}
public final class StringConverter implements Converter<ResponseBody,String> {

    public StringConverter() {
    }

    @Override
    public String convert(ResponseBody value) throws IOException {
        try {
            Log.e("String Converter",value.toString());
            return value.string();
        }finally {
            value.close();
        }
    }
}
public class StringRequestBodyConverter implements Converter<String, RequestBody> {
    private static final MediaType MEDIA_TYPE = MediaType.parse("application/json; charset=UTF-8");
    private static final Charset UTF_8 = Charset.forName("UTF-8");
    public StringRequestBodyConverter() {
    }

    @Override
    public RequestBody convert(String value) throws IOException {
        Buffer buffer = new Buffer();
        Writer writer = new OutputStreamWriter(buffer.outputStream(),UTF_8);
        writer.write(value);
        writer.close();

        return RequestBody.create(MEDIA_TYPE,buffer.readByteString());
    }
}

参考文章
Retrofit的使用与深入学习
Retrofit详解(一)(Retrofit创建过程)
Retrofit自定义Converter之StringConverterFactory

下面是关于异常处理的:
Retrofit+RxJava 优雅的处理服务器返回异常、错误
Retrofit统一处理服务器返回参数
关于Retrofit返回错误信息的统一解决办法

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值