Retroft source code - request interface process

Retrofit uses the tutorial address http://square.github.io/retrofit/source
version

com.squareup.retrofit2:retrofit:2.5.0

Sometimes looking at the source code, I seem to understand but not understand. It's really confusing, so this time I read and debug directly the source code. See retrofit is the execution process.

  1. The first step is to create a Retrofit object, configure some parameters in Retrofit through the creator mode (see the source code for specific parameters), and then perform an example.
  2. The second step is to call the method through the Retrofit instance object create(ApiService.class). This method parses ApiServicethe methods, annotations, and parameters in the interface class through the proxy mode. In its process and by loadServiceMethod(method)caching its methods, annotations, and parameters into private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();it. When loading for the second time, it is directly taken out of the cache and a network loading request is made.
  3. In the third step, the request is loaded successfully, and operations are performed on the data returned by the background.

Through the builder mode, generate a Retrofit instance

   
       /**
     * 创建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);
    }
    

Request the network by calling the create() method


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

As can be seen from the above, through the proxy mode, the methods , parameters , and annotations ApiService.classin it are parsed through this method.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;
    }

First read the network request instance methodfrom the cache serviceMethodCache, and return its instance object directly if it is not empty.
Otherwise, through ServiceMethod.parseAnnotations(this, method)parsing, resultstore its instance object in the cache serviceMethodCacheafter completion

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

It can be seen from the above that through RequestFactory.parseAnnotations(retrofit, method);this method, retrofit is performed, and the method is parsed to generate RequestFactoryan object, and the object is passed into it HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);for parsing to generate ServiceMethoda network request object.

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

Pass retrofit,method,the two instance parameters, pass createCallAdapter(retrofit, method);the parse, and return callAdapterthe instance object. After the adapter conversion and parsing is completed, the instance object createResponseConverter(retrofit, method, responseType);is returned through parsing responseConverter. Finally return new HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter);the instance object.

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

It can be seen that method.getGenericReturnType()the data type model and method.getAnnotations();annotation array are passed into the retrofit.callAdapter(returnType, annotations)method for analysis, and the adapter type of the method is returned.

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

For callAdapterFactoriesthe location of the obtained list, find callAdapterFactories.get(i).get(returnType, annotations, this);the object through the for loop, and return the generated object

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

For converterFactoriesthe location of the obtained list, find converterFactories.get(i).get(returnType, annotations, this);the object through the for loop, and return the generated object

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

This is the last step, instantiating new HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter);the object. In fact, it is a network request instance object ServiceMethod<T>.

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

All the above parameters OkHttpCallare requested through networking, and the data returned by the background is analyzed and called back.

1. Network request interface class,

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. General interface address class Note: The interface address provided by Hongyang Dashen
is used , and you can test it yourself

object ApiUrl {

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

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

}

3. How to use

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

Let's end first.

To sum up, I have done two days of source code research. When you look with your heart, there will always be gains.

Guess you like

Origin blog.csdn.net/u013290250/article/details/85067449