Código fuente retroft - proceso de interfaz de solicitud

Retrofit usa la dirección del tutorial http://square.github.io/retrofit/source
version

com.squareup.retrofit2:retrofit:2.5.0

A veces, mirando el código fuente, parezco entender pero no entender. Es realmente confuso, así que esta vez leí y depuré directamente el código fuente. Ver retrofit es el proceso de ejecución.

  1. El primer paso es crear un objeto Retrofit, configurar algunos parámetros en Retrofit a través del modo creador (consulte el código fuente para conocer los parámetros específicos) y luego realizar un ejemplo.
  2. El segundo paso es llamar al método a través del objeto de instancia Retrofit create(ApiService.class). Este método analiza ApiServicelos métodos, anotaciones y parámetros en la clase de interfaz a través del modo proxy. En su proceso y loadServiceMethod(method)almacenando en caché sus métodos, anotaciones y parámetros en private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();él. Al cargar por segunda vez, se saca directamente de la memoria caché y se realiza una solicitud de carga de red.
  3. En el tercer paso, la solicitud se carga correctamente y se realizan operaciones en los datos devueltos por el fondo.

A través del modo constructor, genere una instancia de 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);
    }
    

Solicite la red llamando al método 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);
          }
        });
  }

Como se puede ver en lo anterior, a través del modo proxy, los métodos , parámetros y anotaciones ApiService.classen él se analizan a través de este método.methodemptyArgsloadServiceMethod(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;
    }

Primero lea la instancia de solicitud de red methoddel caché serviceMethodCachey devuelva su objeto de instancia directamente si no está vacío.
De lo contrario, a través ServiceMethod.parseAnnotations(this, method)del análisis, resultalmacene su objeto de instancia en el caché serviceMethodCachedespués de la finalización

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);
}

A partir de lo anterior, se puede ver que RequestFactory.parseAnnotations(retrofit, method);la actualización se realiza a través de este método, y el método se analiza para generar RequestFactoryun objeto, y el objeto se pasa a él HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);para analizarlo y generar ServiceMethodun objeto de solicitud de red.

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);
    }

Pase retrofit,method,los dos parámetros de instancia, pase createCallAdapter(retrofit, method);el análisis y devuelva callAdapterel objeto de instancia. Una vez completada la conversión y el análisis del adaptador, el objeto de la instancia createResponseConverter(retrofit, method, responseType);se devuelve a través del análisis responseConverter. Finalmente devuelva new HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter);el objeto de instancia.

    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);
  }

Se puede ver que method.getGenericReturnType()el modelo de tipo de datos y method.getAnnotations();la matriz de anotaciones se pasan al retrofit.callAdapter(returnType, annotations)método para su análisis y se devuelve el tipo de adaptador del método.

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());
    }

Para callAdapterFactoriesla ubicación de la lista obtenida, busque callAdapterFactories.get(i).get(returnType, annotations, this);el objeto a través del bucle for y devuelva el objeto generado

  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());
    }

Para converterFactoriesla ubicación de la lista obtenida, busque converterFactories.get(i).get(returnType, annotations, this);el objeto a través del bucle for y devuelva el objeto generado

  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;
  }

Este es el último paso, instanciar new HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter);el objeto. De hecho, es un objeto de instancia de solicitud de red ServiceMethod<T>.

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

Todos los parámetros anteriores OkHttpCallse solicitan a través de la red, y los datos devueltos por el fondo se analizan y se recuperan.

1. Clase de interfaz de solicitud de red,

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. Clase de dirección de interfaz general
Nota: se utiliza la dirección de interfaz proporcionada por Hongyang Dashen , y puede probarla usted mismo

object ApiUrl {

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

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

}

3. Cómo usar

    //配置
    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>
            }
        })

Terminemos primero.

En resumen, he hecho dos días de investigación del código fuente. Cuando miras con tu corazón, siempre habrá ganancias.

Supongo que te gusta

Origin blog.csdn.net/u013290250/article/details/85067449
Recomendado
Clasificación