如遇图片无法加载请点击此链接
我们先从最简单的Retrofit使用方法看
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n7bbuois-1665971394319)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/59fe32aa296d45d685fc5ea05f906458~tplv-k3u1fbpfcp-watermark.image?)]
retrofit最简单的使用方法,只需要设置baseUrl 即可。接口的返回值为Call泛型类型为ResponseBody。
首先来看retrofit的build()方法。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7dT0eJGj-1665971394320)(https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/17a2fe1d743147d2a99691e549a411fc~tplv-k3u1fbpfcp-watermark.image?)]
在build方法中主要流程是
626行用户是否设置了自己的请求客户端,如果没有将使用retrofit中内置的okhttp客户端。
631行是一个回调线程切换器,内部是使用Handler将请求的结果切换到UI线程上,代码如下
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MOK7M4NO-1665971394320)(https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/102ffbad383e402c961773a772751e20~tplv-k3u1fbpfcp-watermark.image?)]
之后的638行是将线程切换器包装成一个DefaultCallAdapterFactory,并放入callAdapterFactories中。
其中DefaultCallAdapterFactory是一个仅支持接口返回类型为Call,且泛型类型为确定类型的类
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-y7zYbMMQ-1665971394321)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/73058130bea44ab5bf00545026cd5d09~tplv-k3u1fbpfcp-watermark.image?)]
之后的代码是将内置的类型转换器BuiltInConverters和platform.defaultConverterFactories()放入converterFactories中。
其中BuiltInConverters只支持返回值类型为ResponseBody,Void,Unit类型
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kEJ6YAT9-1665971394321)(https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/afb464b56b634e23868207b738f93a7a~tplv-k3u1fbpfcp-watermark.image?)]
综上,我们采用最简单的retrofit配置方式,我们的返回值只能支持Call类型且泛型类型为ResponseBody,Void,Unit。
retrofit的build方法结束。
接下来进入retrofit的create方法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qqOK2RiW-1665971394322)(https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e5abcf5bce9e471ba5c65e4060861343~tplv-k3u1fbpfcp-watermark.image?)]
在create方法中,retrofit使用动态的代理的设计模式,对标记在retrofit上的所有注解进行解析饿,create方法中主要是对传入进来的.class对象进行验证。
154行表示,如果方式是Object中的方法直接运行。最后的return判断方法是否是接口实现的默认方法,如果是就直接运行,不是则进入loadServiceMethod(method)方法参数解析。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BbE3QbjV-1665971394323)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/668c57e5a23d4e168820abcaf866d6aa~tplv-k3u1fbpfcp-watermark.image?)]
197行进行参数解析前,retrofit会对解析过的方法进行缓存,防止重复解析。进入ServiceMethod.parseAnnotations方法进行解析。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qP29Hzzj-1665971394323)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/8b5cffe5ba9244088fa7a95a77899753~tplv-k3u1fbpfcp-watermark.image?)]
26行是对注解进行解析,代码比较简单,就是对标注的注解进行检验取值。最后构建出RequestFactory对象
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0uE95JjS-1665971394324)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/72eed56906284cfbac7eeba7d51619c3~tplv-k3u1fbpfcp-watermark.image?)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gU2lSXN4-1665971394324)(https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b217701239484e818248757ef3b5ae8d~tplv-k3u1fbpfcp-watermark.image?)]
经过解析和验证,retrofit此时已经拿到了所有注解的信息。最后进入HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);方法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B89qpGRw-1665971394325)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0cf19c981055443aa0f351e231ca4ecf~tplv-k3u1fbpfcp-watermark.image?)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v5QvubsS-1665971394325)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/cf8da32d42d4499f8bf94ce879fa0da9~tplv-k3u1fbpfcp-watermark.image?)]
这个方法比较长也比较重要,进入该方法后,首先会判断方法的返回值类型是否是协程,如果不是协程将直接取出返回值,并根据返回值,最终调用到CallAdapter.get()方法,确认使用注册的哪种CallAdapter
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x23g2DxO-1665971394326)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0853c7e8cff641ae850458991519dbbe~tplv-k3u1fbpfcp-watermark.image?)]
因为我们这是最简单的使用方法,返回值的类型为Call,也没有注册其他的CallAdapter,所有获取的CallAdapter就是上面DefaultCallAdapterFactory。
之后根据返回值Call传入的泛型,retrofit会寻找合适的类型转换器。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1hMwAvtD-1665971394326)(https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4b22f80488254488ab319da64ad24a28~tplv-k3u1fbpfcp-watermark.image?)]
由于我们没有注册其他的类型转换器,且设置的泛型参数为ResponseBody,所有会进入默认的BuiltInConverters。
至此所有的解析工作完成,最后将要调用Retrofit的create方法中调用.invoke()方法。
invoke()方法的唯一实现类是HttpServiceMethod
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mu9T31P7-1665971394326)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/874f8c7aa7794f5987f3877cd84d3876~tplv-k3u1fbpfcp-watermark.image?)]
invoke方法中并没有直接返回Call对象,而是使用OkHttpCall,将Call对象进行了代理这一步是为了retrofit和okhttp进行解耦。并且将返回值类型使用类型转换器转换类型。之后如果替换okhttp,只需要替换OkhttpCall对象的实现。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2mJahks6-1665971394327)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/104dfc5b384d418e8edf3a52aa537de3~tplv-k3u1fbpfcp-watermark.image?)]
之后继续调用adapt(call,args)方法,由于我们并没有使用协程,所以adapt方法的实现还是在HttpServiceMethod中
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k2iu0WEr-1665971394327)(https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f56d60f2616348a0973ce03279f35027~tplv-k3u1fbpfcp-watermark.image?)]
前面我们已经分析了callAdapter,所以该方法中我们使用的就是DefaultCallAdapterFactory中的callAdapter
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n1joalcb-1665971394328)(https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/45cf408b48b8464d98395387bb55c037~tplv-k3u1fbpfcp-watermark.image?)]
DefaultCallAdapterFactory和我们平时集成LiveDate和Rxjava的CallAdapter一样,最后返回和代理的Call对象,在调用enqueue方法后会讲线程主动切换回UI线程,在DefaultCallAdapterFactory中调用enqueue方法实际回调用okHttpCall代理的enqueue方法,该方法中会调用合适的类型转换器进行转换
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LRpJBdWS-1665971394328)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9733ccf9ec5f456a943e53c3782b89e2~tplv-k3u1fbpfcp-watermark.image?)]