Retrofitソース分析のRetrofitオブジェクト

7337 ワード

ここでは主にRetrofitオブジェクトの作成と.createメソッドについて説明します.基本的にこのクラスのすべての内容が含まれています.
Retrofitオブジェクト
概要
Retrofitはメソッド上の『注釈』を用いてリクエストの構成を定義し,我々が宣言したHttpインタフェースをCallオブジェクトに変換する.
このCallオブジェクトは、先週お話ししたように、同期または非同期メソッドを呼び出してリクエストを送信し、OkHttpに渡して実行することができます.
使用
Retrofitクラスは作成者モードを使用しています.Retrofit.Builderを使用してインスタンスを作成し、Retrofit.create(Class)メソッドを呼び出すと、インタフェース実装クラスを生成できます.
ここではRetrofit関連の使用を振り返ります.
Retrofit retrofit = new Retrofit.Builder()
 .baseUrl("https://api.example.com/")
 .addConverterFactory(GsonConverterFactory.create())
 .build();

 MyApi api = retrofit.create(MyApi.class);

Retrofit.Builder
Retrofit.Builderは、Retrofitオブジェクトのネストされたクラスであり、Retrofitインスタンスオブジェクトを作成するために使用され、「コンストラクタモード」を使用する利点は、カスタマイズ可能であることを明確にすることです.
.build()メソッドを実行する前に、.baseUrl()のみがアクセスアドレスを設定するために呼び出され、残りのメソッドはオプションです.
まず、Builder.build()の最後の戻り文を見てみましょう.
return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
      callbackExecutor, validateEagerly);

ここでのパラメータには、Callファクトリ、アドレス、変換器、CallAdapterファクトリ、Callbackを実行するスレッドプール、validateEagerly IDが含まれます.
次に、いくつかのパラメータを選択して分析します.
baseUrl
baseUrlは、実際にはokHttp 3のHttpUrlクラスのインスタンスであり、httpまたはhttpsプロトコルのURLである.
Retrofit.BuilderにbaseUrlを追加するには、2つのリロード方法baseUrl(String baseUrl)とbaseUrl(HttpUrl baseUrl)がありますが、実際に最後に呼び出されるのは後者です.
public Builder baseUrl(HttpUrl baseUrl) {
  checkNotNull(baseUrl, "baseUrl == null");
  List pathSegments = baseUrl.pathSegments();
  if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
    throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
  }
  this.baseUrl = baseUrl;
  return this;
}

検証を確認すると、RetrofitオブジェクトのURLが設定されていることがわかります.
callbackExecutor
callbackExecutorは、Callback呼び出しでCallbackを実行するためのスレッドプールです.
自分で設定しないと、プラットフォームによってデフォルトのExecutorが設定されます.
if (callbackExecutor == null) {
    callbackExecutor = platform.defaultCallbackExecutor();
  }

ここでの.defaultCallbackExecutor()はPlatform抽象クラスの1つのメソッドです.Converter、Clientなどの属性が含まれています.彼にはAndroid、Java 8、IOSの3つの実装クラスがあります.各プラットフォームのデフォルトパラメータがそれぞれ設定されています.
Retrofit.Buidlerを作成すると、現在の環境のPlatformが取得され、設定されます.
public Builder() {
  this(Platform.get());
}

最後にPlatformのアンドロイド実装クラスを見つけてみましょう.
static class Android extends Platform {
  @Override public Executor defaultCallbackExecutor() {
  return new MainThreadExecutor();
}

  @Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
  return new ExecutorCallAdapterFactory(callbackExecutor);
}

  static class MainThreadExecutor implements Executor {
    private final Handler handler = new Handler(Looper.getMainLooper());

    @Override public void execute(Runnable r) {
    handler.post(r);
    }
  }
}

Handlerメカニズムを知っている人はよく知っているに違いありません.ここではメインスレッドのLooperを取得し、メインスレッドのHandlerを構築します.そこでAndroidプラットフォームでCallbackを呼び出すと、このリクエストをメインスレッドにpostして実行します.
validateEagerly ID
validateEagerlyはブール型のパラメータです
インタフェースメソッドを呼び出すと、プロキシクラスがメソッドのServiceMethodを作成することを知っています.
public  T create(final Class service) {
  Utils.validateServiceInterface(service);
  if (validateEagerly) {
  eagerlyValidateMethods(service);
  }
  ...
}

validateEagerly IDをTrueに設定すると、.eagerlyValidateMethods(service)メソッドを呼び出す前に事前に検証して作成します.
以上がRetrofit.Builderのパラメータと方法で、より具体的には公式ドキュメントを参照して学ぶことができます.
.createメソッド
クラスbuildをネストしてRetrofitオブジェクトを作成することで、次のステップを実行できます.
//HttpインタフェースをCallオブジェクトMyApi api=retrofit.create(MyApi.class);まずcreateメソッドのコードを直接捨てます.コードは多くありません.
public  T create(final Class service) {
  Utils.validateServiceInterface(service);
  if (validateEagerly) {
  eagerlyValidateMethods(service);
  }
  return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class>[] { service },
    new InvocationHandler() {
      private final Platform platform = Platform.get();

      @Override public Object invoke(Object proxy, Method method, 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);
        }
        if (platform.isDefaultMethod(method)) {
          return platform.invokeDefaultMethod(method, service, proxy, args);
        }
        ServiceMethod serviceMethod = loadServiceMethod(method);
        OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
        return serviceMethod.callAdapter.adapt(okHttpCall);
      }
    });
}

次の手順で分析します.
Utils.validateServiceInterface(service);```
validateServiceInterface(service)        Http       Interface,           。         。

if (validateEagerly) { eagerlyValidateMethods(service); }
validateEagerly                ,          。

             ,                          :

return (T) Proxy.newProxyInstance(...);
              Platform,           ,         invoke   。

     invoke          :

if (method.getDeclaringClass() == Object.class) { return method.invoke(this, args); } if (platform.isDefaultMethod(method)) { return platform.invokeDefaultMethod(method, service, proxy, args); }
           Object           ,              ,       isDefaultMethod(method)        false,                         。

ServiceMethod serviceMethod = loadServiceMethod(method);``` 2つの判断を経て、私たちの方法はServiceMethodオブジェクトに変換されます.loadServiceMethodメソッドで何が起こっているかを見てみましょう.
ServiceMethod loadServiceMethod(Method method) {
  ServiceMethod result;
  synchronized (serviceMethodCache) {
    result = serviceMethodCache.get(method);
    if (result == null) {
    result = new ServiceMethod.Builder(this, method).build();
    serviceMethodCache.put(method, result);
    }
  }
  return result;
}```
     ,   Method      ServiceMethod,       ,     。     ServiceMethod     ?              。

         :      Retrofit              Http         Call   。           ServiceMethod      ,                  ,       Call   。

OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args); return serviceMethod.callAdapter.adapt(okHttpCall);``` 次にOkHttpCallを作成します.サービスMethod.CallAdapterを用いてOkHttpCallを変換した.
サービスMethodを作成すると、Retrofitオブジェクトがパラメータとして渡されます.このCallAdapterは、Retrofitを最初に構築したときに追加したCallAdapterFatoryから生成されます.もしあなたが設定していないならば、Androidプラットフォームで、システムはあなたのためにExecutorCallAdapterFactoryを設定します.
ExecutorCallAdapterはまずCallAdapter実装クラスを返します..adapt(okHttpCall)はこのクラスの方法です.
ついに、callAdapter.adaptはokHttpCallをExecutorCallback Callに変換しました.
@Override public  Call adapt(Call call) {
    return new ExecutorCallbackCall<>(callbackExecutor, call);
}```
         .create()      ,    Retrofit            ,           okHttp    。

         ExecutorCallbackCall<>(callbackExecutor, call),     callbackExecutor,      ,   Retrofit.Builder            Executor,         APP       。

              Callback     onResponse   onFailure   ,   post        Handler    。

#####   

       :Retrofit     Http             Call    。