Retrofit 2カスタムCallAdapter

5305 ワード

前言
今回はどのようにCallAdapterを決めますか?ソースのレベルを通してRetrofit 2のCallAdapterを説明します.
まずCallAdapterインターフェースの定義と各方法の役割を見て、コメントを付けました.
public interface CallAdapter {
  //       HTTP       Java         。   , Call       Repo。            adapt call。
  Type responseType();

//       ,   Retrofit create(final Class service)      ,  okHttpCall Call   serviceMethod.callAdapter.adapt(okHttpCall),        Call     
  T adapt(Call call);

//CallAdapter  ,retrofit   DefaultCallAdapterFactory    Call   ,     Call。
abstract class Factory {
//                   ,returnType  Call `Observable`
// RxJavaCallAdapterFactory     returnType   Observable>   
//       null
//      Custom      (    ),  APIService         ,  returnType, : CustomCall getCategories();,   returnType  CustomCall
public abstract @Nullable CallAdapter, ?> get(Type returnType, Annotation[] annotations,
    Retrofit retrofit);

 //             Call   Requestbody
protected static Type getParameterUpperBound(int index, ParameterizedType type) {
  return Utils.getParameterUpperBound(index, type);
}

 //               Call    Call
//   Call         Call
protected static Class> getRawType(Type type) {
  return Utils.getRawType(type);
      }

   }
 }
Retrofitのデフォルトで使用されているDefaultCallAdapter Factoryを見てください.デフォルトでは処理しないでそのままCallに戻ります.
final class DefaultCallAdapterFactory extends CallAdapter.Factory {

static final CallAdapter.Factory INSTANCE = new DefaultCallAdapterFactory();

//     ,     
@Override
public CallAdapter, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
//  APIService        ,   Call,       Call,      ,  null     。
if (getRawType(returnType) != Call.class) {
  return null;
}

//               ,       getParameterUpperBound(0, (ParameterizedType) returnType)  ,       ,      ,    Converter     ,
final Type responseType = Utils.getCallResponseType(returnType);

return new CallAdapter>() {
  @Override public Type responseType() {
    return responseType;
  }
//    Call
  @Override public Call adapt(Call call) {
    return call;
  }
};
}
}
demoがなくていくら言っても無駄です.次はCustomo CallAdapterという名前をカスタマイズします.
  • 第1ステップはCustomallを定義し、Callを専門に扱うデータ
     public static class CustomCall {
    
    public final Call call;
    
    public CustomCall(Call call) {
        this.call = call;
    }
    
    public R get() throws IOException {
          return call.execute().body();
          }
    }
    
  • を処理する.
  • 第二段階CustoomCallAdapterを定義してCustomallへのCall変換を実現します.ここで注意すべきのは最後の汎型です.私達が戻るタイプです.
    public class CustomCallAdapter implements CallAdapter> {
    private final Type responseType;
    
    public CustomCallAdapter(Type responseType) {
      this.responseType = responseType;
    }
    
    /**
     *        , Call    T,  T     Converter.Factory.responseConverter      
     *
     * @return
     */
    @Override
    public Type responseType() {
      return responseType;
      }
    
    @Override
      public CustomCall adapt(Call call) {
          return new CustomCall<>(call);
        }
    }
    
  • 第3部は、RetrofitにCustoomCallAdapter Factoryを提供するためのCustomillAdapterを提供する:
    public class CustomCallAdapterFactory extends CallAdapter.Factory {
    
    public static CustomCallAdapterFactory create() {
      return new CustomCallAdapterFactory();
    }
    
    @Nullable
    @Override
    public CallAdapter, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
    
      //      
      Class> rawType = getRawType(returnType);
    
      //      Custom      (    ),  APIService         ,  returnType
      //  CustomCall getCategories();,   returnType  CustomCall
      if (rawType == CustomCall.class && returnType instanceof ParameterizedType) {
          Type callReturnType = getParameterUpperBound(0, (ParameterizedType) returnType);
          return new CustomCallAdapter(callReturnType);
      }
    
      return null;
      }
    }
    
  • 第4ステップは、addCallAdapter Factoryを使用してRetrofitにCusstomCallAdapter Factory
  • を登録する.
    Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(GitHubService.GLABALURL)
                .addCallAdapterFactory(CustomCallAdapterFactory.create())
                .addConverterFactory(StringConverterFactory.create())
                .addConverterFactory(GsonConverterFactory.create(gson))
                .client(client)
                .build();
    
    注:addCallAdapter FactoryとaddCoverter Factoryは同じで、先着順もあります.
    最後に、retrofitの実行プロセスを見てみましょう.
    create(final Class service)---> loadServiceMethod(method)---->
    ServiceMethod.Builder..build()--->createCallAdapter()--->
    method.getGenericReturnType()--->callAdapter(returnType,   annotations)--->
    nextCallAdapter(null, returnType, annotations)--->
    createResponseConverter()--->method.getAnnotations()--->
    etrofit.responseBodyConverter(responseType, annotations)--->
    nextResponseBodyConverter(null, type, annotations)
    
    上のはretrofitの実行フローです.上の手順ですべてのソースコードを確認できます.
    今回はここまでにして、次のセクションで説明します.文中に手抜かりや間違いがあるかもしれませんので、ご指摘ください.ありがとうございます.