美文网首页
Retrofit 源码分析4-从 invoke 方法看看网络请求

Retrofit 源码分析4-从 invoke 方法看看网络请求

作者: jkwen | 来源:发表于2021-06-12 07:51 被阅读0次

    这次主要分析动态代理实现的 invoke 方法,

    new InvocationHandler(){
        private final Platform platform = Platform.get();
        private final Object[] emptyArgs = new Object[0];
        @Override
        public @Nullable Object invoke(Object proxy, Method method, @Nullable Object[] args) throws Throwable {
            if (method.getDeclaringClass() == Object.class) {
                return method.invoke(this, args);
            }
            args = args != null ? args : emptyArgs;
            return platform.isDefaultMethod(method)
                ? platform.invokeDefaultMethod(method, service, proxy, args)
                : loadServiceMethod(method).invoke(args);
        }
    }
    

    invoke 方法里,主要做了三件事。第一件是判断该方法是不是 Object 的方法,例如 toString, clone 啊等等吧,如果是就以 Object 方法的调用方式执行。第二件是判断该方法是不是 Android 系统方法,这里有个 platform 变量,根据赋值来源就会发现它是用来区分 Java 还是 Android 平台。这点在官网上也有提到,Retrofit 支持 Android 和 Java 平台,显然如果运行在安卓系统上,那就应该是 Android 平台。第三件是调用 loadServiceMethod 方法,这个才是我们需要关心的。

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

    方法的大致逻辑是从 serviceMethodCache 缓存里找到 method 对应的 ServiceMethod 类型对象,如果找不到需要做一次加载,并将对象存入缓存中。这里的加载过程值得我们去关注一下,代码比较多,先分析下大致步骤,

    1. 调用 ServiceMethod 的静态方法 parseAnnotations,大意是利用 Retrofit 对象以及 Method 对象进行解析。
    2. 首先做的就是通过解析创建出一个 RequestFactory 对象,这个对象里包含着很多信息,例如请求方式(即 POST 还是 GET 等请求),请求头,contentType 等等。
    3. 接着通过 HttpServiceMethod 的静态方法 parseAnnotations 进一步解析,入参有 Retrofit 对象,Method 对象和刚才创建的 RequestFactory 对象。
    4. HttpServiceMethod 继承自 ServiceMethod,但也是个抽象类,这个类提供的 parseAnnotations 方法的主要内容是进一步解析,并创建前面说过的适配器和转换器,最后利用 RequestFactory 对象,OkHttp 对象,转换器对象,适配器对象创建了一个 CallAdapted 类型的对象并返回。
    5. CallAdapted 类是 HttpServiceMethod 的子类,实现了父类的抽象方法 adapt。而 HttpServiceMethod 又实现了 ServiceMethod 的抽象方法 invoke,在 invoke 方法里调用了 adapt 方法。
    6. 所以前面说到的加载过程,最终就是返回了一个 CallAdapted 类型的对象,并存到缓存中。接下去就是调用了 CallAdapted 对象的 invoke 方法,显然最终调用了 CallAdapted 自身的 adapt 方法。
    7. CallAdapted 提供的 adapt 方法里就一句,那就是调用适配器的 adapt 方法,并返回一个值。
    8. 前面说过,以 RxJava2CallAdapter 适配器为了,最终就是调用了它的 adapt 方法,入参是 Call 类型对象,这个 Call 就是请求的关键。

    综上,调用网络请求的方法之后就会触发以上的一系列操作,后面将会从两个角度继续分析,一个是看看这个 Call 的生成及后续,一个是看看涉及到的 RxJava2 相关的东西。

    相关文章

      网友评论

          本文标题:Retrofit 源码分析4-从 invoke 方法看看网络请求

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