Retrofit 2の使い方とソース解析

7936 ワード

簡単な紹介
RetrofitはRESTfulアーキテクチャのAndroidクライアントであり、注釈に基づいてJSON to POJO(Plain Ordinary Java Object、簡単Javaオブジェクト)、POJJSON、ネットワーク要求(POST、GET、PUT、DELETEなど)のパッケージを提供する。
ソフトウェアhttp://square.github.io/retrofit/
githubアドレスhttps://github.com/square/retrofit
具体的に使う
公式文書は非常に明確で、Retrofit 2はRetrofitを大幅に改善し、改善について分析し、説明します。
下の階のok httpが違います
Retrofitはデフォルトではok http Retrofit 2を使っています。デフォルトではok http 3を使います。
Serviceインターフェースの定義方式が違います。
Retrofit 2の前に同期の関数が定義されるなら、このように定義されるべきである。
public interface GitHubService {
  
    @POST("/list")
    Repo loadRepo();
  
}
非同期関数定義
public interface GitHubService {
  
    @POST("/list")
    void loadRepo(Callback cb);
  
}
Retrofit 2同期非同期方法はインターフェースを定義すればいいです。
mport retrofit.Call;
public interface GitHubService {
  
    @POST("/list")
    Call loadRepo();
  
}
同期要求を呼び出すなら、executeを呼び出すだけです。非同期要求を開始するのは、enqueueを呼び出すことである。
Retrofit 2は、要求方法をキャンセルすることができる。
Retrofit 2はCallの使用を要求していますが、callにはキャンセル方法があります。要求をキャンセルすることができます。call.cancelを呼び出すだけでキャンセルできます。
Coverterは現在Retrofit 2から削除されており、必要に応じてCoverterを導入する必要があります。
ここはスクウェアが提供している公式Coverter modulesのリストです。あなたの要求に一番満足するものを選んでください。
Gson: com.squareup.retrofit:converter-gson
Jackson: com.squareup.retrofit:converter-jackson
Moshi: com.squareup.retrofit:converter-moshi
Protobuf: com.squareup.retrofit:converter-protobuf
Wire: com.squareup.retrofit:converter-wire
Simple XML: com.squareup.retrofit:converter-simplexml
Retrofit 2の新しいURL定義方式RetrofitインターフェースはURL要求用/先頭を設定しなければならず、インターフェース要求URLは完全なパスではない。Entdpointを使用してサーバパスを切り替えることができます。
Retrofit 2における新しいURL定義方式については、推奨する。
-Base URL:常に/で終了します。
-@Url:始めにしないでください。
Retrofit 2にはEndpointというクラスがありません。@Urlにはフルコースが含まれています。フルコースbaseUrlは無視されます。
public interface APIService {
    @POST("http://api.test.com/test)
    Call loadUsers();
}
Retrofit 2はOkHttpのサポートが必要です。
OkHttpはRetrofitで選択できます。もしあなたがRetrofitをHTTP接続インターフェースとしてOkHttpを使用したいなら、手動でokhttp依存を含む必要があります。しかし、Retrofit 2ではOkHttpが必要であり、依存に自動的に設定されている。Retrofit 2 INTERNETの権限がないとSecurityException異常がRetrofitにあります。Android Manifest.xmlファイルにINTERNETの権限を追加することを忘れたら。非同期要求は直接にfailureフィードバック方法に進み、PERMISON DENIEDエラーメッセージを得る。何の異常もなく投げ出されました。しかし、Retrofit 2では、cal.enqueueまたはcal.executeを呼び出すと、すぐにSecurity Exceptionを抛り出します。try-catchを使わないと崩壊します。
レスポンスに問題があったとしてもonResonseは起動されます。
Retrofitでは、取得したレスポンスが定義されたオブジェクトに逆解析できない場合には、failureを呼び出します。しかし、Retrofit 2では、reponseが解析されるかどうかに関わらず。ワンストップは常に呼び出されます。しかし、結果が解析できない場合は、レスポンス.body()はnullに戻ります。異常を出すだけでオンフォーレを呼び出すことができます。
スクリーンショットが違います
Retrofitでは、Request Interceptorを使用して一つの要求をブロックすることができますが、HTTP接続層はすでにOkHttpに完全に移行していますので、Retrofit 2から削除されました。Retrofit 2はokhttpのスクリーンセーバーを使用しています。
ソース分析
Retrofitの作成
Retrofitはfinal類で、サブクラスを定義することができません。Retrofitはpublic構造方法がなく、構築した者方式Retrofit.Bulderを使って構築するしかありません。
etrofit.Buiderは、urlルートアドレス、採用されたネットワーククライアント、コールスレッドプール、要求ブロック、リターンデータフォーマット器、およびエラー処理を指定することができる。
通常はbaseUrl、addCoverterFactoryという二つの方法を呼び出さなければなりません。
構築器はデフォルトではOkHttpClientをネットワーク要求ツールとして使用し、addCallAdapter Factoryは要求インスタンスを構築するために使用され、calbackExectorはコールバック方法スレッド池を指定し、プラットフォームの構築によって、AndroidはdefaultCallbackExectorで構築され、デフォルトはメインスレッドにある。validateEagerlyはデフォルトでfalseとなり、実行する時にコメントを解析します。trueに設定すると、createの例の後、インターフェースのすべての方法を解析します。
if (baseUrl == null) {
       throw new IllegalStateException("Base URL required.");
     }
 public  T create(final Class service) {
    Utils.validateServiceInterface(service);
    if (validateEagerly) {
      eagerlyValidateMethods(service);
    }
    return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class>[] { service },
......
 
  

Retrofit create , , , Object , , 。 , Retrofit 。
  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);
          }
        });
インターフェースの
まず、キャッシュから の を して、 に ってきます。そうでなければ、 を つけて、キャッシュに れます。 したインターフェースはserviceMethodCacheに され、 り し を し、 を させます。 はServiceMethod.Buiderを いて を する。
build に、まずcalAdapterを します。
に の があり、 が されると が します。
で したパラメータは、 ではなく、 データタイプではなく、voidではありません。
は ではありません
calAdapterを した 、 のServiceMethod を し けます。 の な に してください。
るタイプはレスリングできません。
http Methodコメントは ではありません。
にbodyがない 、MultiiPadとFormEncodedパラメータタイプを できないのは タイプと パラメータではないです。 URLがないと、 きForm-encoded は なくとも つ@Field MultiiPad を んでいます。 の を たすために、ServiceMethodを しく することができます。
  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;
  }
  public ServiceMethod build() {
      callAdapter = createCallAdapter();
      responseType = callAdapter.responseType();
      if (responseType == Response.class || responseType == okhttp3.Response.class) {
        throw methodError("'"
            + Utils.getRawType(responseType).getName()
            + "' is not a valid response body type. Did you mean ResponseBody?");
      }
      responseConverter = createResponseConverter();
......
ネットワーク
が したら、CallAdapterのadaptメソッドを び してCallに ります。
は の りです
public CallAdapter> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
    if (getRawType(returnType) != Call.class) {
      return null;
    }
    final Type responseType = Utils.getCallResponseType(returnType);
    return new CallAdapter>() {
      @Override public Type responseType() {
        return responseType;
      }

      @Override public  Call adapt(Call call) {
        return new ExecutorCallbackCall<>(callbackExecutor, call);
      }
    };
  }
この では を していません。コールを いて、 に されたのはExectrrCallbackCallです。 に を するのはコール のエージェントdelegateです。このエージェントの はOkHttpcallです。Retrofit 2はOKhttp に を することに します。 execute は、Okhttpclient の であり、
ちょっとお きしたいのですが、okhttpからの の です。
  private okhttp3.Call createRawCall() throws IOException {
    Request request = serviceMethod.toRequest(args);
    okhttp3.Call call = serviceMethod.callFactory.newCall(request);
    if (call == null) {
      throw new NullPointerException("Call.Factory returned null.");
    }
    return call;
  }
を した 、コールバックExectorを してメインスレッドを します。
Retrofit 2はRetrofitよりも く されていますが、 はより くなりました。 に です。ネットワーク の みとして、コード にスレッド が われていないのは、Okhttp が をよくしているからです。 のモジュールの を に し、 の を しました。
コードをスキャンして、 に してください。