Retrofit 原理解析(一)

作者: zcwfeng | 来源:发表于2020-12-28 18:36 被阅读0次

    从使用入口看整体的结构

    // 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

    相关文章

      网友评论

        本文标题:Retrofit 原理解析(一)

        本文链接:https://www.haomeiwen.com/subject/pziznktx.html