移动 前端 Python Android Java

Retrofit 原理解析(一)

2020-12-28  本文已影响0人  zcwfeng

从使用入口看整体的结构

// TODO: Retrofit 使用步骤
    private fun testRetrofit() {
        //TODO 1. 构建一个retrofit对象
        val retrofit = Retrofit.Builder()
            //Retrofit2的baseUrl 必须以 /(斜杆)结束,抛出一个IllegalArgumentException
            .baseUrl("https://www.wanandroid.com/")
            .addConverterFactory(GsonConverterFactory.create())
            .build()

        //TODO 2. 获取WanAndroidApi接口的代理对象
        val wanAndroidApi = retrofit.create(WanAndroidApi::class.java)

        //TODO 3. 获取具体的请求业务方法
        val projectCall = wanAndroidApi.getProject()

        //TODO 发起请求
        // 同步 val projectBean  = projectCall.execute()
        // 异步
        projectCall.enqueue(object : Callback<ProjectBean> {
            override fun onFailure(call: Call<ProjectBean>, t: Throwable) {
                Log.i(TAG, "错误:${t.message}")
            }

            override fun onResponse(call: Call<ProjectBean>, response: Response<ProjectBean>) {
                Log.i(TAG, "成功: ${response.body()}")
            }

        })
    }
retrofit 总流程
BuildRequest (接口-注解)------配置网络请求参数(注解)
Call(网络请求执行器)--------------创建网络请求对象
CallAdapter(网络请求适配器)-----适配具体的Call
Call(网络请求执行器)------------发送网络请求,代理模式
Convert(数据转换器)--------数据返回,解析数据

Retrofit#Builder#build() 方法 这是一个构建者模式

看到这个设计模式,我们会思考,构造retrofit实例 动态变的和不变的是什么。
参数肯定有一些是必须的或者内部帮我们创建好的,还有一些固定的流程肯定是不变的,根据这个思路,我们继续研究

1.1 build() 构建的参数
okhttp3.Call.Factory callFactory 

Executor callbackExecutor

List<CallAdapter.Factory> callAdapterFactories =  。。。
callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));

List<Converter.Factory> converterFactories  = 。。。
converterFactories.add(new BuiltInConverters());
converterFactories.addAll(this.converterFactories);
 converterFactories.addAll(platform.defaultConverterFactories());
  1. callFactory
    只要我们使用了build后,默认callFactory创建出来为OkHttpClient
if (callFactory == null) {
        callFactory = new OkHttpClient();
      }
  1. Executor callbackExecutor

接下来我们发现一个很重要的成员platform

这个是在Retrofit#Builder() 中进行赋值的,目的区分平台,对java8支持的判断,获取MainThreadExecutor作为默认defaultCallbackExecutor,

private final Handler handler = new Handler(Looper.getMainLooper());

很关键的一句是Android平台主线程,证明请求是主线成开始的。

  1. List<CallAdapter.Factory> callAdapterFactories
    制作适配器的防御副本并添加默认的适配器

  2. List<Converter.Factory> converterFactories
    制作转换器的防御性副本

先添加内置转换器工厂。这可以防止重写其行为,但也可以确保在使用使用所有类型的转换器时行为正确。

1.2 api = create(final Class<T> service)
  1. validateServiceInterface
  2. 返回一个动态代理一个动态代理
    创建接口类WanAndroidApi 对象,这样可以让所有的访问请求都走这个代理,动态代理存在api对应的函数,函数里会调用invoke,也就是retrofit里面的invoke。这样拦截调用函数的执行,将网络接口参数配置归一化

代理最终返回ServiceMethod 通过Retrofit#loadServiceMethod

根据parseAnnotations注解的解析,返回 HttpServiceMethod

ServiceMethod<?> loadServiceMethod(Method method) {
    ServiceMethod<?> result = serviceMethodCache.get(method);
    if (result != null) return result;

    synchronized (serviceMethodCache) {
      result = serviceMethodCache.get(method);
      if (result == null) {
        result = ServiceMethod.parseAnnotations(this, method);
        serviceMethodCache.put(method, result);
      }
    }
    return result;
  }

解析后的ServiceMethod 存到了缓存
private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();

Call ---- val projectCall = wanAndroidApi.getProject()

返回了api 定义具体业务Callback

发起请求
DefaultCallAdapterFactory#ExecutorCallbackCall#delegate#enqueue

请求之后的回调,在我们一开始默认callAdapterFactories 加入的DefaultCallAdapterFactor#CallAdapter
将Call接口转换成业务Bean(Object)
Call 就是中间的委托delegate结构

2020-12-28 18.30.04.png
上一篇下一篇

猜你喜欢

热点阅读