Retroft ソース コード - リクエスト インターフェイス プロセス

Retrofit ではチュートリアルのアドレスhttp://square.github.io/retrofit/source
versionを使用します。

com.squareup.retrofit2:retrofit:2.5.0

ソースコードを見てみると、わかっているようで理解できないこともあります。非常にややこしいので、今回はソースコードを直接読んでデバッグしてみます。レトロフィットは実行プロセスを参照してください。

  1. 最初のステップでは、Retrofit オブジェクトを作成し、クリエイター モードを通じて Retrofit でいくつかのパラメータを設定し (特定のパラメータについてはソース コードを参照)、サンプルを実行します。
  2. 2 番目のステップは、Retrofit インスタンス オブジェクトを通じてメソッドを呼び出すことですcreate(ApiService.class)このメソッドは、ApiServiceプロキシ モードを通じてインターフェイス クラスのメソッド、アノテーション、およびパラメーターを解析します。そのプロセス内で、loadServiceMethod(method)メソッド、アノテーション、パラメータをキャッシュすることによってprivate final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();2回目のロード時はキャッシュから直接取り出してネットワークロード要求を行います。
  3. 3 番目のステップでは、リクエストが正常にロードされ、バックグラウンドから返されたデータに対して操作が実行されます。

ビルダー モードを通じて、Retrofit インスタンスを生成します。

   
       /**
     * 创建Retrofit 实例,并针对参数进行配置
     * Create the {@link Retrofit} instance using the configured values.
     * <p>
     * Note: If neither {@link #client} nor {@link #callFactory} is called a default {@link
     * OkHttpClient} will be created and used.
     */
    public Retrofit build() {
        if (baseUrl == null) {
            throw new IllegalStateException("Base URL required.");
        }

        okhttp3.Call.Factory callFactory = this.callFactory;
        if (callFactory == null) {
            //实例OkhttpClient对象
            callFactory = new OkHttpClient();
        }

        Executor callbackExecutor = this.callbackExecutor;
        if (callbackExecutor == null) {
            callbackExecutor = platform.defaultCallbackExecutor();
        }
        //默认配置返回参数适配器,例如,返回RxJava2CallAdapterFactory
        // Make a defensive copy of the adapters and add the default Call adapter.
        List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
        //会传一个默认的适配器
        callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
        //默认配置返回的数据类型,比如GSON(GsonConverterFactory),XML,
        // Make a defensive copy of the converters.
        List<Converter.Factory> converterFactories = new ArrayList<>(
                1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());

        // 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);
        converterFactories.addAll(platform.defaultConverterFactories());
        //通过建造者模式,返回Retrofit实例
        return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
                unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
    }
    

create() メソッドを呼び出してネットワークを要求します。


  public <T> T create(final Class<T> service) {
  //判断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();
          //存储方法里面的传参
          private final Object[] emptyArgs = new Object[0];
         //通过代理模式
          @Override public Object invoke(Object proxy, Method method, @Nullable 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);
            }
            //通过该方法实现网络通讯
            return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
          }
        });
  }

上記からわかるように、プロキシ モードでは、そのApiService.class中のメソッドmethod、パラメータemptyArgs、およびアノテーションloadServiceMethod(method)がこのメソッドを通じて解析されます。

    ServiceMethod<?> loadServiceMethod(Method method) {
        //获取serviceMethodCache的缓存
        ServiceMethod<?> result = serviceMethodCache.get(method);
        if (result != null) return result;

        synchronized (serviceMethodCache) {
            //根据method获取网络请求实例
            result = serviceMethodCache.get(method);
            //如果缓存是空的
            if (result == null) {
                //则解析method
                result = ServiceMethod.parseAnnotations(this, method);
                //解析完成后,存入serviceMethodCache,
                serviceMethodCache.put(method, result);
            }
        }
        //返回网络请求实例
        return result;
    }

まずネットワーク リクエスト インスタンスをmethodキャッシュから読み取りserviceMethodCache、空でない場合はそのインスタンス オブジェクトを直接返します。
それ以外の場合は、ServiceMethod.parseAnnotations(this, method)解析を通じて、完了後にresultそのインスタンス オブジェクトをキャッシュに保存しますserviceMethodCache

abstract class ServiceMethod<T> {
  static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
  //主要的在这里,parseAnnotations
    RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);

    Type returnType = method.getGenericReturnType();
    if (Utils.hasUnresolvableType(returnType)) {
      throw methodError(method,
          "Method return type must not include a type variable or wildcard: %s", returnType);
    }
    if (returnType == void.class) {
      throw methodError(method, "Service methods cannot return void.");
    }

    return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
  }

  abstract T invoke(Object[] args);
}

RequestFactory.parseAnnotations(retrofit, method);上記から、このメソッドを通じてレトロフィットが実行され、メソッドが解析されてRequestFactoryオブジェクトが生成され、そのオブジェクトが解析HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);のためにメソッドに渡されてServiceMethodネットワーク要求オブジェクトが生成されることがわかります。

static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
            Retrofit retrofit, Method method, RequestFactory requestFactory) {
        //创建适配器,RxJava
        CallAdapter<ResponseT, ReturnT> callAdapter = createCallAdapter(retrofit, method);
        //获取callAdapter响应类型
        Type responseType = callAdapter.responseType();
        if (responseType == Response.class || responseType == okhttp3.Response.class) {
            throw methodError(method, "'"
                    + Utils.getRawType(responseType).getName()
                    + "' is not a valid response body type. Did you mean ResponseBody?");
        }
        if (requestFactory.httpMethod.equals("HEAD") && !Void.class.equals(responseType)) {
            throw methodError(method, "HEAD method must use Void as response type.");
        }
        //创建数据类型转换器,比如Gson,
        Converter<ResponseBody, ResponseT> responseConverter =
                createResponseConverter(retrofit, method, responseType);
        //将其OkHttpClient对象 赋值给  callFactory
        okhttp3.Call.Factory callFactory = retrofit.callFactory;
        //将其解析完成的参数对象,传入HttpServiceMethod构造方法当中进行实例,并返回
        return new HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter);
    }

retrofit,method,2 つのインスタンス パラメーターを渡し、createCallAdapter(retrofit, method);解析を渡し、callAdapterインスタンス オブジェクトを返します。アダプターの変換と解析が完了すると、インスタンス オブジェクトcreateResponseConverter(retrofit, method, responseType);が解析を通じて返されますresponseConverter最後にnew HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter);インスタンス オブジェクトを返します。

    private static <ResponseT, ReturnT> CallAdapter<ResponseT, ReturnT> createCallAdapter(
            Retrofit retrofit, Method method) {
        //获取方法返回的数据类型模型
        Type returnType = method.getGenericReturnType();
        //获取方法注解
        Annotation[] annotations = method.getAnnotations();
        try {
            //noinspection unchecked
            //通过retrofit对象callAdapter方法进行解析,完事后返回适配器实例对象
            return (CallAdapter<ResponseT, ReturnT>) retrofit.callAdapter(returnType, annotations);
        } catch (RuntimeException e) { // Wide exception range because factories are user code.
            throw methodError(method, e, "Unable to create call adapter for %s", returnType);
        }
    }
    
 public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
    return nextCallAdapter(null, returnType, annotations);
  }

method.getGenericReturnType()データ型モデルとmethod.getAnnotations();アノテーション配列が分析のためにメソッドに渡されretrofit.callAdapter(returnType, annotations)、メソッドのアダプター型が返されることがわかります。

public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
                                             Annotation[] annotations) {
   	.....
   	
        //获取callAdapterFactories列表的索引,
        int start = callAdapterFactories.indexOf(skipPast) + 1;
        //针对列表进行循环查找,实例 CallAdapter适配器,返回该实例对象
        for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
            CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
            if (adapter != null) {
                return adapter;
            }
        }
	 
	 省略以下代码
     .....
        throw new IllegalArgumentException(builder.toString());
    }

callAdapterFactories取得したリストの場所は、forループでオブジェクトを検索しcallAdapterFactories.get(i).get(returnType, annotations, this);生成されたオブジェクトを返します。

  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);
    }
  }
  
  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;
        for (int i = start, count = converterFactories.size(); i < count; i++) {
            Converter<ResponseBody, ?> converter =
                    converterFactories.get(i).responseBodyConverter(type, annotations, this);
            if (converter != null) {
                //noinspection unchecked
                return (Converter<ResponseBody, T>) converter;
            }
        }

        省略部分代码
        ...
        throw new IllegalArgumentException(builder.toString());
    }

converterFactories取得したリストの場所は、forループでオブジェクトを検索しconverterFactories.get(i).get(returnType, annotations, this);生成されたオブジェクトを返します。

  private HttpServiceMethod(RequestFactory requestFactory, okhttp3.Call.Factory callFactory,
      CallAdapter<ResponseT, ReturnT> callAdapter,
      Converter<ResponseBody, ResponseT> responseConverter) {
    this.requestFactory = requestFactory;
    this.callFactory = callFactory;
    this.callAdapter = callAdapter;
    this.responseConverter = responseConverter;
  }

これが最後のステップで、new HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter);オブジェクトをインスタンス化します。実際、これはネットワーク リクエスト インスタンス オブジェクトですServiceMethod<T>

//调用传入网络方法请求参数
 @Override ReturnT invoke(Object[] args) {
    return callAdapter.adapt(
        new OkHttpCall<>(requestFactory, args, callFactory, responseConverter));
  }

上記のパラメータはすべてOkHttpCallネットワークを通じてリクエストされ、バックグラウンドから返されたデータが分析されてコールバックされます。

1. ネットワークリクエストインターフェースクラス、

interface ApiService {

    @GET("/article/list/{page}/json")
    fun getListArticleData(@Path("page") page: Int): Call<BaseData<ArticleData>>

    @GET("/project/list/{page}/json")
    fun getListData(@Path("page") page: Int, @Query("cid") cid: Int): Call<BaseData<ArticleData>>
}

2. 一般的なインターフェイス アドレス クラス注: Hongyang Dashenによって提供されるインターフェイス アドレス
が使用され、自分でテストできます。

object ApiUrl {

    val BASE_URL = "http://www.wanandroid.com"

    var ARTICLE_LIST = "/article/list/{page}/json"

}

3. 使用方法

    //配置
    implementation 'com.squareup.retrofit2:retrofit:2.5.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.5.0'
  1.实例 Retrofit对象
  val retrofit = Retrofit.Builder()
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .baseUrl(ApiUrl.BASE_URL)
            .build()
  2.通过代理方法创建api接口类
  val apiService = retrofit.create(ApiService::class.java)
  3.调用接口内部的方法
  val listArticleData = apiService.getListArticleData(1)
  4.通过接口方法返回的实例进行回调,操作后台返回的数据
  listArticleData.enqueue(object : Callback<BaseData<ArticleData>> {
  //联网失败或数据解析失败
      override fun onFailure(call: Call<BaseData<ArticleData>>, t: Throwable) {
                println("t = $t")
            }
            //联网成功,后台返回数据
     override fun onResponse(call: Call<BaseData<ArticleData>>, response: Response<BaseData<ArticleData>>) {
                val mutableList: MutableList<ArticleData> = response.body()!!.data!!.datas as MutableList<ArticleData>
            }
        })

まず終わりにしましょう。

要約すると、私は 2 日間のソース コード調査を行いました。心で見つめれば、必ず得るものがあるのです。

おすすめ

転載: blog.csdn.net/u013290250/article/details/85067449
おすすめ