[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S8L4CTCX-1656725069031)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ffa3fa2439714c76a0b10cc1c0e22770~tplv-k3u1fbpfcp-zoom-1.image)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1NV02cb6-1656725069033)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/3d01e827bca946e78e54bd364b6e738e~tplv-k3u1fbpfcp-zoom-1.image)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BEmlSWdk-1656725069034)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/07ca6fe95c884764b271701e2818652e~tplv-k3u1fbpfcp-zoom-1.image)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MK3eUzx0-1656725069035)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/1c7996f6005f43a99e9a7bf31aa2b7a2~tplv-k3u1fbpfcp-zoom-1.image)]
这里的ConcurrentHashMap就是一个ConcurrentHashMap
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9NTDu0yz-1656725069036)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/eb0f92a57f2842c58852d087cc30fd03~tplv-k3u1fbpfcp-zoom-1.image)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OepXw8uG-1656725069037)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/df2a9c2e25284155a422029151007c7b~tplv-k3u1fbpfcp-zoom-1.image)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NT1HgKZH-1656725069039)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c99e73cccb704e3da256a20eaa9b8a38~tplv-k3u1fbpfcp-zoom-1.image)]
上面的第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方法就可以了。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qRtzjUBL-1656725069046)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c6270f23cc3c4e73a4e4e96fcdfffafa~tplv-k3u1fbpfcp-zoom-1.image)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G4swbxMP-1656725069047)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/682065e86950440bb7fb9b150215fa27~tplv-k3u1fbpfcp-zoom-1.image)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cP7hceLc-1656725069048)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/db7595ad530542b282c0b235a99c9a3a~tplv-k3u1fbpfcp-zoom-1.image)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JtmJZ71h-1656725069048)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/12265abdfe5d43ae815f91fe3eaf63ae~tplv-k3u1fbpfcp-zoom-1.image)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HozJmdgr-1656725069049)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/95ce6edf10434146828a0db2caacee63~tplv-k3u1fbpfcp-zoom-1.image)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rMS36ahO-1656725069049)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/47d6a021f46c40f1be8ffbe8405dc11a~tplv-k3u1fbpfcp-zoom-1.image)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Pli5KLFl-1656725069049)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/478f41f39a0f44f0947bf64bdced9662~tplv-k3u1fbpfcp-zoom-1.image)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h8HtDwWg-1656725069050)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/eec5c03d6c9b43949af7a79e049d4ea8~tplv-k3u1fbpfcp-zoom-1.image)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z73JJqBA-1656725069050)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7cf15a663080489888328e716e36e4b4~tplv-k3u1fbpfcp-zoom-1.image)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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很简单,就一个,调用它的convert方法的时候,会直接把原装的RequestBody返回。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-koKcdQVk-1656725069051)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7f543203b47b4501b38f2fe4f707e569~tplv-k3u1fbpfcp-zoom-1.image)]
响应的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类型就是我们期望的实体类类型)。