• android源码宇宙-Retrofit


    Retrofit使用

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S8L4CTCX-1656725069031)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ffa3fa2439714c76a0b10cc1c0e22770~tplv-k3u1fbpfcp-zoom-1.image)]

    Retrofit源码

    主流程

    1. 源码查看入口

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1NV02cb6-1656725069033)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/3d01e827bca946e78e54bd364b6e738e~tplv-k3u1fbpfcp-zoom-1.image)]

    1. Retrofit动态代理监听

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BEmlSWdk-1656725069034)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/07ca6fe95c884764b271701e2818652e~tplv-k3u1fbpfcp-zoom-1.image)]

    1. validateServiceInterface如何进行合法性校验和方法初始化

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MK3eUzx0-1656725069035)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/1c7996f6005f43a99e9a7bf31aa2b7a2~tplv-k3u1fbpfcp-zoom-1.image)]

    1. 接着第2步和第3步看loadServiceMethod方法

    这里的ConcurrentHashMap就是一个ConcurrentHashMap

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9NTDu0yz-1656725069036)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/eb0f92a57f2842c58852d087cc30fd03~tplv-k3u1fbpfcp-zoom-1.image)]

    1. 看看ServiceMethod.parseAnnotations是如何创建ServiceMethod的

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OepXw8uG-1656725069037)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/df2a9c2e25284155a422029151007c7b~tplv-k3u1fbpfcp-zoom-1.image)]

    1. HttpServiceMethod.paresAnnotations方法,获取ServiceMethod方法

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6DwV5QT6-1656725069037)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/660f298f98fe432787fd9a3df743e341~tplv-k3u1fbpfcp-zoom-1.image)]
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DGKJzLEX-1656725069038)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/1fdd97aabf0b405fb48dd822016744db~tplv-k3u1fbpfcp-zoom-1.image)]
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dv9TKZtk-1656725069039)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7d56b6b0b11d4df6b70e139db632845f~tplv-k3u1fbpfcp-zoom-1.image)]

    1. 两种kotlin的HttpServiceMethod(SuspendForResponse、SuspendForBody)的实现的内部原理

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NT1HgKZH-1656725069039)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c99e73cccb704e3da256a20eaa9b8a38~tplv-k3u1fbpfcp-zoom-1.image)]

    1. HttpServiceMethod的执行

    上面的第6/7步生成了一个ServiceMethod,ServiceMethod就是Retrofit桥接okhttp的关键代码。
    在第2步中loadServiceMethod后会使用invoke方法执行请求,如下:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-27eaIDKJ-1656725069039)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/40a6f9be32dc4a4d8bcede2d8e2e8c1a~tplv-k3u1fbpfcp-zoom-1.image)]
    然后我们发现invoke是ServiceMethod中的方法,没有被子类实现。它内部实现如下:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-On98e8nu-1656725069040)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a58709f9b7dd4a8187a7cf4dd636a3ce~tplv-k3u1fbpfcp-zoom-1.image)]
    也就是说invoke方法中会调用adapt方法,而这个adapt方法是需要子类实现的。所以我们去看adapt方法就可以了。

    1. 主流程结束

    Retrofit是如何代理Okhttp的

    1. 首先使用一个OkHttpCall内部持有一个okhttp3.Call对象

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xVw4lNUZ-1656725069040)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9b2cf858c16a41e4bc83631e29c907da~tplv-k3u1fbpfcp-zoom-1.image)]

    2. OkhttpCall内部有executed方法和enqueue方法,内部会调用rawCall的相关方法实现代理okhttp3.Call
    例如1,executed方法
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2ykDiX3C-1656725069041)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/70a820bc9a5f46eba8a4ebe93eade2d7~tplv-k3u1fbpfcp-zoom-1.image)]
    而enqueue方法,内部会使用okhttp3.AsyncCall.enqueue进行异步请求,在相关的回调方法中响应回调数据。
    这里的call的实际类型是OkHttpCall
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pFGnaUXG-1656725069042)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/97de0a48a10247fb9b12426e88d7ace2~tplv-k3u1fbpfcp-zoom-1.image)]

    CallAdapter.Factory是如何工作的

    1. 设置CallAdapterFactory的方法

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qRtzjUBL-1656725069046)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c6270f23cc3c4e73a4e4e96fcdfffafa~tplv-k3u1fbpfcp-zoom-1.image)]

    1. Retrofit是会有默认的CallAdapter.Factory 的,创建默认CallAdapter.Factory位置如下

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3emCAwgq-1656725069046)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/35df5296a76c4b179aec770d2199ef55~tplv-k3u1fbpfcp-zoom-1.image)]

    3. HttpServiceMethod.parseAnnotations方法中获取使用CallAdapter.Factory
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EbhaynGW-1656725069047)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/659dfd2e8d1349e9b4db87e7ab691860~tplv-k3u1fbpfcp-zoom-1.image)]

    1. 将callAdapter传入ServiceMethod中

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G4swbxMP-1656725069047)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/682065e86950440bb7fb9b150215fa27~tplv-k3u1fbpfcp-zoom-1.image)]

    1. 我们分别看看CallAdapted和SuspendForResponse两种的实现
    • CallAdapted

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cP7hceLc-1656725069048)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/db7595ad530542b282c0b235a99c9a3a~tplv-k3u1fbpfcp-zoom-1.image)]

    • SuspendForResponse

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JtmJZ71h-1656725069048)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/12265abdfe5d43ae815f91fe3eaf63ae~tplv-k3u1fbpfcp-zoom-1.image)]

    1. 结束

    Converter.Factory是如何工作的

    1. 构建请求的时候可以设置解析工厂类

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HozJmdgr-1656725069049)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/95ce6edf10434146828a0db2caacee63~tplv-k3u1fbpfcp-zoom-1.image)]

    1. 然后会把解析工厂添加到Retrofit中

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rMS36ahO-1656725069049)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/47d6a021f46c40f1be8ffbe8405dc11a~tplv-k3u1fbpfcp-zoom-1.image)]

    1. 我们是如何使用converter工厂的

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Pli5KLFl-1656725069049)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/478f41f39a0f44f0947bf64bdced9662~tplv-k3u1fbpfcp-zoom-1.image)]

    1. 当执行HttpServiceMethod的invoke方法的时候会构建OkhttpCall

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h8HtDwWg-1656725069050)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/eec5c03d6c9b43949af7a79e049d4ea8~tplv-k3u1fbpfcp-zoom-1.image)]

    1. 使用Converter解析返回结果

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z73JJqBA-1656725069050)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7cf15a663080489888328e716e36e4b4~tplv-k3u1fbpfcp-zoom-1.image)]

    1. 返回最终结果

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fEzhBjS3-1656725069050)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9048e5b8a8f84c1cb4e3624206f09b1c~tplv-k3u1fbpfcp-zoom-1.image)]
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m2kDHaTh-1656725069051)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/02c9c6b0a76e4e06a8193e22b9daffbd~tplv-k3u1fbpfcp-zoom-1.image)]

    默认的请求Converter

    请求的默认Converter很简单,就一个,调用它的convert方法的时候,会直接把原装的RequestBody返回。
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-koKcdQVk-1656725069051)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7f543203b47b4501b38f2fe4f707e569~tplv-k3u1fbpfcp-zoom-1.image)]

    默认的响应Converter

    响应的Converter有多种,如下图
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CybJkVgX-1656725069051)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c7900beeb2674e199539b25f1f6b5450~tplv-k3u1fbpfcp-zoom-1.image)]

    总结

    Retrofit在调用Retrofit.create创建Service接口实例的时候,会创建一个动态代理的监听。每次我们调用Service方法的时候就会回调动态代理的invoke方法。然后在动态代理的回调里面会经过多重逻辑处理后,调用loadServiceMethod创建ServiceMethod实例,ServiceMethod是一个抽象类,他有三个默认的实现类,分别是CallAdapted、SuspendForResponse、SuspendForBody,其中后两个用在suspend方法协程中的。
    loadServiceMethod返回ServiceMethod后,会调用ServiceMethod的invoke方法,invoke方法是在父类ServiceMethod中的(需要强调的是,我们后面提到的OkHttpCall也是在这个方法中创建的),invoke方法中会调用adapt方法,adapt方法每个子类中都会实现。子类中会调用callAdapter.adapt获取响应Response,然后不同的ServiceMethod实现会执行自己的逻辑对Response处理,最终会返回一个Call对象,默认会返回retrofit2.OkHttpCall类型。
    上一段中返回了一个OkHttpCall类型,然后我们会调用executed或enqueue同步或异步获取请求结果。例如调用enqueue的时候,OkHttpCall.enqueue内部会调用okhttp3.Call.enqueue执行请求,请求成功后会使用回调接口来回调数据(需要强调的是在OkHttpCall的enqueue和execute方法中都会调用parseResponse方法对响应进行处理,在parseResponse方法中会调用我们的converter对结果进行处理,然后包装成一个新的Response类型,新的Response中的body就是我们期望的返回类型。默认的Response.body是ResponseBody类型,如果使用GsonConverterFactory进行处理,Response.body类型就是我们期望的实体类类型)。

  • 相关阅读:
    【c++百日刷题计划】 ———— DAY13,奋战百天,带你熟练掌握基本算法
    MATLAB算法实战应用案例精讲-【工具应用篇】matlab遗传算法工具箱使用方法
    matlab根轨迹绘制
    Linux终端、关机、ldd、ldconfig等系统命令
    JAVA电视设备租借系统计算机毕业设计Mybatis+系统+数据库+调试部署
    【AcWing单源最短路建图】1126. 最小花费
    点分治学习笔记 / 洛谷 P3806【点分治】
    企业知识库有什么价值?
    解析大型语言模型的训练、微调和推理的运行时性能
    基于51单片机超市称重电子秤proteus仿真
  • 原文地址:https://blog.csdn.net/ymeddmn/article/details/125569125