Retrofit2使用方式和源码解析

Android 网络框架之Retrofit源码解析,满满干货指导 算法知识点繁多,企业考察的题目千变万化,面对越来越近的“金九银十”,我给大家准备好了一套比较完善的学习方法,希望能帮助大家在有限的时间里尽可能系统快速的恶补算法,通过高效的学习来提高大家面试中算法模块的通过率。这一套学习资料既有文字档也有视频,里面不仅仅有关键知识点的整理,还有案例的算法相关部分的讲解,可以帮助大家更好更全面的进行学习,二者搭配起来学习效果会更好。部分资料展示:有了这套学习资料,坚持刷题一周,你就会发现自己的算法知识体系有明显的完善,离大厂Offer的距离更加近。【GitHub】 阅读详情

简单介绍

Retrofit是一套RESTful架构的Android(Java)客户端实现,基于注解,提供JSON to POJO(Plain Ordinary Java Object,简单Java对象),POJO to JSON,网络请求(POST,GET,PUT,DELETE等)封装。

软件首页http://square.github.io/retrofit/

github地址https://github.com/square/retrofit

具体使用

官方文档非常清晰,Retrofit2对Retrofit做了很大改进,针对改进做一下分析和使用说明

底层okhttp不同

Retrofit 默认使用okhttp
Retrofit2 默认使用okhttp3

Service接口定义方式不同

在Retrofit2之前如果定义一个同步的函数,应该这样定义:
public interface GitHubService {
  
    @POST("/list")
    Repo loadRepo();
  
}
异步函数定义
public interface GitHubService {
  
    @POST("/list")
    void loadRepo(Callback<Repo> cb);
  
}
Retrofit2 同步异步方法定义一个接口就可以了
mport retrofit.Call;
public interface GitHubService {
  
    @POST("/list")
    Call<Repo> loadRepo();
  
}

如果要调用同步请求,只需调用execute;而发起一个异步请求则是调用enqueue。

Retrofit2 可以取消请求方法

Retrofit2请求使用Call,Call有cancel方法可以取消请求
只需调用call.cancel()就可以取消请求。

Converter现在从Retrofit2中删除,需要根据自己的需要引入Converter

这里是Square提供的官方Converter modules列表。选择一个最满足你需求的。
Gson: com.squareup.retrofit:converter-gson
Jackson: com.squareup.retrofit:converter-jackson
Moshi: com.squareup.retrofit:converter-moshi
Protobuf: com.squareup.retrofit:converter-protobuf
Wire: com.squareup.retrofit:converter-wire
Simple XML: com.squareup.retrofit:converter-simplexml

Retrofit2 新的URL定义方式

Retrofit接口请求URL要求用/开头,必须设置baseUrl,接口请求URL不能是完整路径。可以使用Endpoint切换服务器路径
于 Retrofit2中新的URL定义方式,建议
- Base URL: 总是以 /结尾
- @Url: 不要以 / 开头
Retrofit2中没有Endpoint这个类,@Url中可以包含完整的路径,包含完整路径baseUrl会被忽略
public interface APIService {
    @POST("http://api.test.com/test)
    Call<Users> loadUsers();
}

Retrofit2 需要OkHttp的支持

OkHttp在Retrofit里是可选的。如果你想让Retrofit 使用OkHttp 作为HTTP 连接接口,需要手动包含okhttp 依赖。
但是在Retrofit2中,OkHttp 是必须的,并且自动设置为了依赖。
Retrofit2缺少INTERNET权限会导致SecurityException异常
在Retrofit 中,如果忘记在AndroidManifest.xml文件中添加INTERNET权限。异步请求会直接进入failure回调方法,得到PERMISSION DENIED 错误消息。没有任何异常被抛出。但是在Retrofit2中,当调用call.enqueue或者call.execute,将立即抛出SecurityException,如果不使用try-catch会导致崩溃。

即使response存在问题onResponse依然被调用

在Retrofit中,如果获取的 response 不能背解析成定义好的对象,则会调用failure。但是在Retrofit2中,不管 response 是否能被解析。onResponse总是会被调用。但是在结果不能被解析的情况下,response.body()会返回null。只有抛出异常才会调用onFailure

拦截器不同

在Retrofit中,可以使用RequestInterceptor来拦截一个请求,但是它已经从Retrofit2 移除了,因为HTTP连接层已经完全转为OkHttp。
Retrofit2使用okhttp的拦截器


源码分析

Retrofit的创建

Retrofit是个final类,不能再定义子类,Retrofit没有public构造方法,只能使用构建的者方式Retrofit.Builder构建。
etrofit.Builder可以指定url根地址、采用的网络客户端、回调线程池、请求拦截器、返回数据格式器和错误处理。
通常必须调用baseUrl,addConverterFactory这两个方法。
构建器默认使用OkHttpClient作为网络请求工具,addCallAdapterFactory用来构建请求实例,callbackExecutor指定回调方法线程池,根据不同平台构建不同,Android构建的是defaultCallbackExecutor,默认在主线程中。validateEagerly默认为false,表示执行的时候再去解析注解。如果设置为true,那么create实例之后,就会先解析接口所有方法。

if (baseUrl == null) {
       throw new IllegalStateException("Base URL required.");
     }<pre name="code" class="java"> public <T> T create(final Class<T> service) {
    Utils.validateServiceInterface(service);
    if (validateEagerly) {
      eagerlyValidateMethods(service);
    }
    return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
......


请求实例的创建

调用Retrofit的create方法,创建了执行请求对象的代理,代理方法的执行中,对于Object方法和默认方法,直接执行,其它方法解析后执行。使用代理加注解,是Retrofit的核心思想。
  return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
        new InvocationHandler() {
          private final Platform platform = Platform.get();

          @Override public Object invoke(Object proxy, Method method, Object... args)
              throws Throwable {
            // If the method is a method from Object then defer to normal invocation.
            if (method.getDeclaringClass() == Object.class) {
              return method.invoke(this, args);
            }
            if (platform.isDefaultMethod(method)) {
              return platform.invokeDefaultMethod(method, service, proxy, args);
            }
            ServiceMethod serviceMethod = loadServiceMethod(method);
            OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
            return serviceMethod.callAdapter.adapt(okHttpCall);
          }
        });

接口的解析过程

loadServiceMethod中首先从缓存中找解析的方法,找到直接返回,否则解析方法,然后放入缓存中。解析过的接口保存在了serviceMethodCache中,防止重复解析,提高效率。解析方法使用ServiceMethod.Builder构建解析器。
build过程中,首先创建callAdapter,
解析中有一系列规则,发现异常会抛出异常
方法返回的参数不能是泛型,不能是基本数据类型,不能是void。
注解不能为空
创建完callAdapter继续构建其他ServiceMethod属性,需要注意其他抛出异常的情况
返回类型不能是一个Response
httpMethod注解不能为空
如果请求中没有body,不能使用Multipart和FormEncoded
参数类型不能是基本类型和泛型
参数不能没有注解
URL不能为空
Form-encoded方法至少包含一个@Field注解
Multipart方法至少包含一个@Part注解
满足以上要求,才能正确构建ServiceMethod。
  ServiceMethod loadServiceMethod(Method method) {
    ServiceMethod result;
    synchronized (serviceMethodCache) {
      result = serviceMethodCache.get(method);
      if (result == null) {
        result = new ServiceMethod.Builder(this, method).build();
        serviceMethodCache.put(method, result);
      }
    }
    return result;
  }

  public ServiceMethod build() {
      callAdapter = createCallAdapter();
      responseType = callAdapter.responseType();
      if (responseType == Response.class || responseType == okhttp3.Response.class) {
        throw methodError("'"
            + Utils.getRawType(responseType).getName()
            + "' is not a valid response body type. Did you mean ResponseBody?");
      }
      responseConverter = createResponseConverter();
......

网络请求处理

方法解析完成之后,调用CallAdapter的adapt方法返回Call
内部构建如下
public CallAdapter<Call<?>> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
    if (getRawType(returnType) != Call.class) {
      return null;
    }
    final Type responseType = Utils.getCallResponseType(returnType);
    return new CallAdapter<Call<?>>() {
      @Override public Type responseType() {
        return responseType;
      }

      @Override public <R> Call<R> adapt(Call<R> call) {
        return new ExecutorCallbackCall<>(callbackExecutor, call);
      }
    };
  }
此时并没有发起请求,只是构建除了call,具体来说构建的是ExecutorCallbackCall,真正用来执行请求的是call内部的代理delegate,这个代理的真实身份是OkHttpCall,Retrofit2相当于将请求全权交给OKhttp处理,异步请求enqueue方法,同步请求execute方法都是执行的Okhttpclient对应的方法,
一下是okhttp请求的真实创建方法
  private okhttp3.Call createRawCall() throws IOException {
    Request request = serviceMethod.toRequest(args);
    okhttp3.Call call = serviceMethod.callFactory.newCall(request);
    if (call == null) {
      throw new NullPointerException("Call.Factory returned null.");
    }
    return call;
  }
异步执行完之后,利用callbackExecutor将回调抛回主线程。

Retrofit2比Retrofit简化了很多,但是功能却更加强大了。真的非常奇妙。作为网络请求框架,整个代码中居然没有用线程池,因为Okhttp本身对异步处理已经做的很好了。充分发挥了其它模块的功能,简化了自身逻辑。



欢迎扫描二维码,关注公众号





Retrofit 2.9.0 源码解析 Retrofit 源码解析,a.Retrofit是如何通过声明来实现网络请求的;b.Retrofit是如何支持Kotlin协程的(即如何使用suspend来实现将直接转换为Response的呢);c.Retrofit在设计中使用了哪些设计模式呢; 阅读详情

相关推荐

Java开发者必看:5分钟搞定PaddleOCR表格识别,导出Excel和HTML超详细教程

本文为Java开发者提供了集成PaddleOCR实现智能表格识别的详细教程,包括环境配置、核心代码实现、结果导出到Excel和HTML的步骤,以及性能优化技巧。通过PaddleOCR技术,开发者可以快速将图片表格转换为结构化数据,大幅提升工作效率。

weixin_30872499的博客 98

Retrofit动态设置baseUrl和@url的使用

一. Retrofit动态设置baseUrl有四种方式: 配置多个retrofit对象:即不同的 BaseUrl 使用不同的 Retrofit 对象来创建 ApiService 进行请求,这样只要新增一个不同的 BaseUrl ,那就需要重新创建一个新的 Retrofit 对象。 缺点:代码冗余,浪费资源,ApiService太多,不好管理。 @Get , @Post 全路径:这些标注到每个接口方法上的注解不仅可以传相对路径,还可以传全路径,这样我们就可以做到不同的接口使用不同的 BaseUrl ,使用全

liuxiaopang520的博客 1万+

最新,弱小目标检测数据集,持续更新中。

梳理了最新的下弱小目标检测数据库,方便后续开发使用

weixin_43331421的博客 4092

Retrofit 2 动态URL

问题使用Retrofit2一般都是针对于一baseURL,其它接口都是拼接不同的参数如get/photo,search?name=xiaohong&&sex=female,这样的形式。但是一些请求此时又要访问不同的url只能重新生成一个Retrofit2实例,实质上还有一种形式去处理,就是使用@url注解。解决方案public interface UserService { @GET

小小程序员 1万+

2024年11月架构设计师案例分析真题回顾,附参考答案、解析及所涉知识点(一)

软考高级系统架构设计师考试包含三个科目:信息系统综合知识、案例分析和系统架构设计论文。考试形式为机考。本文主要回顾2024年下半年(2024-11-10)系统架构设计师考试上午第二科案例分析的题目,同时附带参考解答、解析和所涉知识点。

一几文的编程学习笔记。 2418

[密码学实战]密评考试训练系统v1.0程序及密评参考题库(获取路径在文末)(二十四)

本系统将密码学理论与软件工程实践相结合,为密评备考提供了高效解决方案。随着《密码法》的深入实施,掌握密评知识将成为信息安全从业者的核心竞争力。立即开始您的密码安全专家之旅!(注:实际应用请以最新发布版本为准)

曼岛_的博客 796

Android开发之路—网络请求篇Retrofit2.0的使用

参考文章: https://blog.csdn.net/m0_37796683/article/details/90702095 文章目录一、前言1、Retrofit是什么二、Retrofit注解类型1、网络请求方法注解2、标记类注解3、网络请求参数注解三、Retrofit的使用方法1、添加依赖2、添加网络权限3、创建用于描述网络接口的类4、创建Retrofit的实例5、创建网络接口请求示例6、完...

飞兔的博客 1962

【光子AI 2026 企业级 Agent 架构指南】别再把 Skill 当 Tool:Agent Skills × MCP 企业级落地全指南(最新定义澄清 + 场景大全 + 选型决策树+安全工程清单)

摘要: 2026年企业级AI架构迎来两大核心标准——Agent Skills与MCP(Model Context Protocol),分别解决流程标准化与系统集成难题。Agent Skills通过“文件夹化能力包”(SOP+脚本+模板)固化专家流程,确保输出一致性;MCP则以类USB-C的协议统一外部系统接入,降低集成成本。两者差异显著:Skills专注程序性知识(如财报生成),MCP侧重动态连接(如跨平台数据调用)。实际场景中,复杂需求(如智能客服)需组合使用——MCP为骨架提供连接能力,Skills为大

AI天才研究院 2469

Retrofit2讲解

Retrofit2学习分析详解,附接口,附遇见问题分析

qq_52332769的博客 7132

43、FMCW雷达高度计仿真

本文介绍了FMCW雷达高度计的波形级建模与仿真过程,重点模拟了着陆和倾斜两种飞行场景以评估其性能。通过结合高程数据和飞行轨迹构建雷达场景,使用自定义信号处理器分析IQ样本并估计高度。结果表明,该高度计在多数情况下满足性能要求,但也存在误差较大的点,提出了地面检测算法优化的潜在方向。

neovim7hacker的博客 135

2026最新版OpenClaw安装:Windows WSL2从零到跑通

Windows WSL2安装OpenClaw指南 本文详细介绍了在Windows系统上通过WSL2部署OpenClaw AI助理的完整流程。WSL2结合了Windows易用性和Linux高性能,特别适合Windows用户、开发者、学生和技术爱好者。文章涵盖硬件要求(推荐i5/16GB/SSD)、系统准备(Windows 10/11+WSL2)、环境部署(Python/Node.js/Redis)和OpenClaw配置(克隆/编译/初始化)等关键步骤。通过WSL2,用户可在保留Windows操作习惯的同

一键难忘的博客 2345

Retrofit常见注解全解析

​导语Android开发圈中这三者Retrofit+RxJava+MVP结合使用的频率已经相当高了,很多圈内大神也已经总结了很多有关于整合这三者的博客,已经很多了,今天写这篇文章主要就不再介绍了。不过很多人并不了解Retrofit的全部注解使用,今天的重点就是要介绍日常常用的Retrofit的注解。1、什么是Retrofit?Retrofit 是一个Square开发的安卓客户端请求库。其中内部封装了

1104

【车载以太网】Eth Stack Bringup

摘要:本文基于AUTOSAR架构,详细介绍了在TC3xx硬件平台上实现EthStack Bringup的全过程。作者通过配置MCAL和Davinci工具,完成了EthTrcv、Eth、EthIf、EthSM和TcpIp等模块的集成,并解决了16字节内存对齐和以太网速率不匹配等问题。最终实现了PC端与开发板的Ping通,并通过WireShark验证了数据包收发。文章总结了调试中的关键问题与解决方案,强调了实践的重要性,为后续EthStack的深入分析奠定了基础。

qq_36056498的博客 180

Retrofit 2.x上传文件的两种方式及源码分析

Retrofit 2.x上传文件的两种方式及源码分析

Civitasv 1106

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

Android 知识梳理目录 - 好吧,这是一个很“干“的标题

Android 数据存储知识梳理(1) - SQLiteOpenHelper 源码解析 Android 数据存储知识梳理(2) - Android存储目录 Android 数据存储知识梳理(3) - SharedPreference 源码解析 Android 数据存储知识梳理(4) - 数据库升级操作的处理策略 2.7 状态栏 Android 状态栏知识点总结 2.8 广播 Broadcast 知识梳理(1) - BroadcastReceiver 基本概念 2.9 Service Service 知

m0_61362539的博客 211

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Retrofit源码解析

square公司开源了一系列的优秀库,比如Retrofit,OkHttp,Picasso等, 前面简单分析了Picasso的源码,这里来分析下Retrofit的使用:一、gradle添加依赖compile 'com.squareup.okhttp:okhttp:2.4.0' compile 'com.squareup.okhttp:okhttp-urlconnection:2.4.0' compi

woliuyunyicai的专栏 1万+

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

【项目实践06】【Retrofit2 框架的使用】

最近项目需要使用coze的功能,因此在引入 coze 提供的 SDK 时看到其使用了 Retrofit2 内容,简单了解后得知 Retrofit2 封装了网络请求功能。巧就巧在目前正在开发的项目中有一个模块功能需要调用大量三方 API,因此决定使用 Retrofit2 来完成 Http 请求。Retrofit2 是一个适用于 Android 和 Java 的类型安全的 HTTP 客户端框架,由 Square 公司开发。

猫吻鱼的博客 1770

Android Retrofit2使用详解及从源码中解析原理

就目前来说Retrofit2使用的已相当的广泛,那么我们先来了解下两个问题: 1 . 什么是Retrofit? Retrofit是针对于Android/Java的、基于okHttp的、一种轻量级且安全的、并使用注解方式的网络请求框架。 2 . 我们为什么要使用Retrofit,它有哪些优势? 首先,Retrofit使用注解方式,大大简化了我们的URL拼写形式,而且注解含义一目了然,简单易懂; 其次,Retrofit使用简单,结构层次分明,每一步都能清晰的表达出之所以要使用的寓意; 再者,Retrofit支持

summer0012的博客 651

展开说说Android之Retrofit详解_源码解析

本文主要从六个方面分析了Retrofit源码实现:首先介绍了Retrofit的核心类和接口,包括Retrofit类、ServiceMethod类等;接着解析了@GET、@POST等注解的作用;然后通过OkHttpCall类揭示了Retrofit封装OkHttp的实现;解释了Retrofit异步请求能在主线程返回的原理;梳理了请求的完整流程;最后总结了Retrofit的优缺点。文章详细呈现了Retrofit从注解解析到最终请求实现的完整机制,特别是通过动态代理和线程切换的实现细节

Hidanchaofan的博客 1034

Retrofit2深度解析

Retrofit2深度解析 一、简介 本文基于implementation 'com.squareup.retrofit2:retrofit:2.5.0' 编写 Retrofit2大致的使用步骤如下: 1.初始化Retrofit 2.构建网络请求 3.发送请求,解析数据 我们通过使用顺序来一步一步解析源码 首先,看初始化的代码 Retrofit retrofit = new Retrofit.Bu...

矢的飞跃的专栏 889

Android 网络框架之Retrofit2使用详解及从源码中解析原理

就目前来说Retrofit2使用的已相当的广泛,那么我们先来了解下两个问题:1 . 什么是Retrofit?Retrofit是针对于Android/Java的、基于okHttp的、一种轻量级且安全的、并使用注解方式的网络请求框架。2 . 我们为什么要使用Retrofit,它有哪些优势?首先,Retrofit使用注解方式,大大简化了我们的URL拼写形式,而且注解含义一目了然,简单易懂;其次,Retro

管满满 3万+

Retrofit源码全方面解析

如今作为一个Android开发者,网络请求这块离不开square公司的全家桶,今天我们就来分析一下其中的Retrofit框架的源码。 为什么使用Retrofit 因为方便、直观,和OkHttp的结合天衣无缝: @GET("weather") fun weather(@Query("latitude") latitude: String, @Query("longitude") longitude: String): Flowable<String> 通过注解,对于这样的一个GET请求,请求参数

xlh1191860939的博客 2490

Android Retrofit 源码解析

一、前言 前面的一篇文章《Android OkHttp 源码解析 - 整体流程分析》已经对 OkHttp 网络请求框架有一个大概的了解。现在我们来学习一下 Retrofit。Retrofit 是 square 公司的另一款广泛流行的网络封装框架,它是对网络请求的封装,不是一个网络框架,retrofit 里面网络框架还是由 okhttp 内核来做。 今天同样地对 Retrofit 的源码进行详细...

lerendan的博客 817

Retrofit2源码解析

Retrofit2源码解析 Retrofit实际上是一个网络请求框架的封装,它的核心是使用OkHttp来进行网络请求。 完成OkHttp数据的转化和适配工作 Retrofit使用了动态代理 八个步骤 创建retrofit实例 定义网络请求接口,并添加注解 通过 动态代理 生成网络请求对象 通过 网络请求适配器 将网络请求对象 进行平台适配 通过 网络请求执行器(Call) 发送网络...

mingC0758的博客 300
上一篇: 算法系列(六)数据结构之表队列和栈
下一篇: 设计模式系列(一)单例模式
robert_chao
博客等级 码龄15年 265粉丝 119原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值