retrofit 2.6.1源碼解析(二)converter


Retrofit支持Gson,進行數據轉換

引入,很輕量呀,就3個類

  • GsonConverterFactory,用於構建GsonConverter的工廠類

  • GsonRequestBodyConverter,將Java對象轉換爲RequestBody

  • GsonResponseBodyConverter,將ResponseBody轉換爲Java對象

implementation 'com.squareup.retrofit2:converter-gson:2.6.1'
 Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://api.github.com/")
                .addConverterFactory(GsonConverterFactory.create(new Gson())) //增加對Gson庫的支持
                .build();

在這裏插入圖片描述

構建responseConverter

第一篇中,getServiceMethod()中,會構造 responseConver對象,假使我們註冊了GsonConverterFactory

  • 通過retrofit的converterFactories去取factory,默認下標從0開始

  • Converter.Factory是個抽象類,有兩個抽象方法,分別提供requestBodyConverter,ResponseBodyConverter

  • GsonConverterFactory實現了Converter.Factory,分別提供GsonRequestBodyConverter,GsonResponseBodyConverter

//HttpServiceMethod.java

 //得到responseConver對象,使用自定義,或內置的
Type responseType = callAdapter.responseType();
Converter<ResponseBody, ResponseT> responseConverter
		 = createResponseConverter(retrofit, method, responseType);

private static <ResponseT> Converter<ResponseBody, ResponseT> createResponseConverter(
      Retrofit retrofit, Method method, Type responseType) {
    Annotation[] annotations = method.getAnnotations();
    try {
      return retrofit.responseBodyConverter(responseType, annotations);
    } catch (RuntimeException e) { // Wide exception range because factories are user code.
      throw methodError(method, e, "Unable to create converter for %s", responseType);
    }
  }
//Retrofit.java
public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) {
    return nextResponseBodyConverter(null, type, annotations);
  }

  public <T> Converter<ResponseBody, T> nextResponseBodyConverter(
      @Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) {
 
    int start = converterFactories.indexOf(skipPast) + 1; //start從0開始
    for (int i = start, count = converterFactories.size(); i < count; i++) {
      Converter<ResponseBody, ?> converter =
          converterFactories.get(i).responseBodyConverter(type, annotations, this);
        return (Converter<ResponseBody, T>) converter;
    }
  }

Retrofit2.6.1包中的Converter接口

public interface Converter<F, T> {
  @Nullable T convert(F value) throws IOException;

  /** Creates {@link Converter} instances based on a type and target usage. */
  abstract class Factory {
   
   //responseBody
    public @Nullable Converter<ResponseBody, ?> responseBodyConverter(Type type,
        Annotation[] annotations, Retrofit retrofit) {
      return null;
    }

    public @Nullable Converter<?, RequestBody> requestBodyConverter(Type type,
        Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
      return null;
    }
  }
}

GsonConverterFactory

  • GsonConverterFactory 繼承了Converter.Factory,工廠類

  • responseBodyConverter() 返回GsonResponseBodyConverter對象,

  • requestBodyConverter() 返回requestBodyConverter對象

TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));

首先都通過T的類對象,得到TypeAdapter對象,默認是通過反射來實現的。

Gson 2.8.5源碼解析(一)

public final class GsonConverterFactory extends Converter.Factory {
  
  //提供一個統一的Gson對象
  public static GsonConverterFactory create() {
    return create(new Gson());
  }
//返回一個GsonConverterFactory
  public static GsonConverterFactory create(Gson gson) {
    return new GsonConverterFactory(gson);
  }

  private final Gson gson;

  private GsonConverterFactory(Gson gson) {
    this.gson = gson;
  }

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

  //將Java對象轉換爲RequestBody
  @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);
  }
}

GsonRequestBodyConverter

將Java對象轉換爲RequestBody

final class GsonRequestBodyConverter<T> implements Converter<T, RequestBody> {
  private static final MediaType MEDIA_TYPE = MediaType.get("application/json; charset=UTF-8");
  private static final Charset UTF_8 = Charset.forName("UTF-8");

  private final Gson gson;
  private final TypeAdapter<T> adapter;

  GsonRequestBodyConverter(Gson gson, TypeAdapter<T> adapter) {
    this.gson = gson;
    this.adapter = adapter;
  }

  @Override public RequestBody convert(T value) throws IOException {
    Buffer buffer = new Buffer();
    Writer writer = new OutputStreamWriter(buffer.outputStream(), UTF_8);
    JsonWriter jsonWriter = gson.newJsonWriter(writer);
    adapter.write(jsonWriter, value);
    jsonWriter.close();
    return RequestBody.create(MEDIA_TYPE, buffer.readByteString());
  }
}

GsonResponseBodyConverter

將ResponseBody轉換爲Java對象

final class GsonResponseBodyConverter<T> implements Converter<ResponseBody, T> {
  private final Gson gson;
  private final TypeAdapter<T> adapter;

  GsonResponseBodyConverter(Gson gson, TypeAdapter<T> adapter) {
    this.gson = gson;
    this.adapter = adapter;
  }

  @Override public T convert(ResponseBody value) throws IOException {
    JsonReader jsonReader = gson.newJsonReader(value.charStream());
    try {
      T result = adapter.read(jsonReader);
      if (jsonReader.peek() != JsonToken.END_DOCUMENT) {
        throw new JsonIOException("JSON document was not fully consumed.");
      }
      return result;
    } finally {
      value.close();
    }
  }
}

總結:

requestConverter(將java對象轉換爲requestBody):

  • 在RequestFactory類中,retrofit.requestBodyConverter()得到Converter<?, RequestBody>對象

  • 通過retrofit遍歷converterFactories,factory.requestBodyConvert(),返回converter對象

     如果是GsonConverterFactory返回的GsonRequestBodyConverter
     java對象,序列化爲Json字符串,字符串通過RequestBody.create()轉換爲RequestBody對象
    

responseConverter(將ResponseBody轉換爲java對象):

  • 在HttpServiceMethod類中,retrofit.responseBodyConverter()得到Converter<ResponseBody, ?>對象

  • 通過retrofit遍歷converterFactories,factory.responseBodyConverter(),返回converter對象

     如果是GsonConverterFactory返回的GsonResponseBodyConverter
     gson.newJsonReader(value.charStream()),得到jsonReader,typeAdapter.read(jsonReader)返回T
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章