Android 面试系列:Retrofit 的 suspend 是如何实现的?

作者:潜龙勿用之化骨龙日期:2026/7/30

今天这个是送分题,但是仍然有很多人不清楚,今天就聊聊这个

比如:

1interface UserApi {
2
3    @GET("user")
4    suspend fun getUser(): User
5
6}
7

调用:

1val user = api.getUser()
2

这里 Retrofit 并不是同步等待网络结果。

它只是把原来的异步流程转换成了 Kotlin 协程可以理解的挂起恢复流程。所以你不要再withContext 一下。


Retrofit 是怎么知道这是 suspend 方法?

Kotlin 的 suspend 函数在编译后,会增加一个隐藏参数:

1Object getUser(
2    Continuation<? super User> continuation
3)
4

也就是说:

1suspend fun getUser(): User
2

实际上类似:

1getUser(Continuation)
2

Retrofit 在解析接口方法时,会检查方法参数。

如果发现最后一个参数是:

1Continuation
2

就认为:

这是 Kotlin suspend 方法。

Retrofit 内部如何处理 suspend 方法?

核心类:

1HttpServiceMethod
2

Retrofit 根据不同返回类型创建不同的处理方式。

对于:

1suspend fun getUser(): User
2

会创建:

1SuspendForBody
2

它负责把:

1Call<User>
2

转换成:

1User
2

SuspendForBody 内部做了什么?

核心逻辑类似:

1suspend fun <T> Call<T>.await(): T {
2
3    return suspendCancellableCoroutine { continuation ->
4
5        enqueue(object : Callback<T> {
6
7            override fun onResponse(
8                call: Call<T>,
9                response: Response<T>
10            ) {
11
12                continuation.resume(
13                    response.body()!!
14                )
15
16            }
17
18
19            override fun onFailure(
20                call: Call<T>,
21                error: Throwable
22            ) {
23
24                continuation.resumeWithException(error)
25
26            }
27
28        })
29    }
30}
31

它主要完成三件事:

  1. 发起异步请求
1enqueue()
2
  1. 保存当前协程执行状态
1Continuation
2
  1. 请求完成后恢复协程

成功:

1continuation.resume()
2

失败:

1continuation.resumeWithException()
2

这里通过 suspendCancellableCoroutine 把原来的callback 转成 suspend


这里的 await 是 Kotlin 协程提供的吗?

不是。

这里的:

1await()
2

只是 Retrofit 定义的扩展函数。

它只是一个名字。

真正关键的是:

1suspendCancellableCoroutine
2

以及:

1Continuation.resume()
2

那 Kotlin 协程里的 await 是什么?

Kotlin 协程也有一个 await:

1val result = async {
2    request()
3}.await()
4

这个属于:

1Deferred.await()
2

作用:

等待另一个协程任务完成。

而 Retrofit 的:

1Call.await()
2

作用:

把网络请求结果转换成协程结果。

两个不是同一个东西。


Retrofit suspend 底层是不是阻塞线程?

不是。

它不会:

1线程等待网络
2

而是:

1调用接口
2
3
4
5协程挂起
6
7
8
9线程释放
10
11
12
13OkHttp 执行网络请求
14
15
16
17结果回来
18
19
20
21Continuation.resume()
22
23
24
25协程继续执行
26

等待的是:

异步结果


Retrofit suspend 会切换 Dispatchers.IO 吗?

Retrofit 不负责线程调度。

网络线程:

1OkHttp Dispatcher
2

协程恢复:

1Coroutine Dispatcher
2

两个职责不同。

那异常为什么可以直接 try catch?

因为 Retrofit 把 Callback 的失败转换成协程异常。

以前:

1onFailure()
2

异常在回调里。

现在:

1continuation.resumeWithException(error)
2

协程状态机收到异常后:

等价于:

1throw error
2

所以:

1try {
2    api.getUser()
3} catch(e:Exception){
4
5}
6

可以捕获。


总结 Retrofit suspend 原理

Retrofit 的 suspend 支持,本质是通过动态代理识别 suspend 方法,利用 Continuation 将 OkHttp 的异步结果转换成协程挂起恢复流程,让 Callback 风格的 API 变成 suspend 风格的 API。


Android 面试系列:Retrofit 的 suspend 是如何实现的?》 是转载文章,点击查看原文


相关推荐


为什么学习 Go?Go 能做什么?
程序员爱钓鱼2026/7/22

Go 编程实战系列(一) 近年来,无论是云计算、容器技术、微服务,还是人工智能基础设施,Go(又称 Golang)几乎都占据着重要位置。从 Docker、Kubernetes 到 Prometheus、Etcd,再到大量互联网公司的后端服务,Go 已经成为现代服务端开发的重要语言之一。 对于刚开始学习编程的人来说,可能会有这样几个问题: Go 为什么越来越流行? Go 和 Java、Python、Rust、C++ 有什么区别? 学 Go 能做哪些项目? 学完 Go 能找到什么工


Cursor安全插件链:代码审计新范式
lideiguo2026/7/13

一、 引言:当AI代码助手成为安全审计的“双刃剑” 核心问题:随着 Cursor、GitHub Copilot 等 AI 代码助手的普及,开发效率大幅提升,但同时也引入了新的安全风险——AI 生成的代码可能存在漏洞,而开发者可能因过度信任而疏于审计。 新范式诞生:“安全插件链”应运而生,它通过将静态代码分析、依赖检查、漏洞扫描等安全工具与 Cursor 等 IDE 深度集成,在代码生成、修改、提交等关键环节自动介入,形成“开发即审计”的闭环。 本文目标:探讨 Cursor 安全插件链的核心


基于MATLAB图像处理的饮料瓶识别与价格显示系统设计与实现
7zcode2026/7/5

摘要:随着图像处理技术在商品识别、智能零售和自动检测领域的广泛应用,传统依靠人工判断饮料种类和价格的方式存在效率低、主观性强、信息统计不便等问题。针对饮料瓶图像识别与价格自动显示需求,本文设计并实现了一套基于MATLAB图像处理的饮料瓶识别与价格显示系统。 项目概览 项目简介 本文设计并实现了一种基于MATLAB的饮料瓶智能识别与价格统计系统。该系统采用计算机视觉技术,结合HSV颜色空间阈值分割和形状特征分析两种识别方法,实现对常见饮料瓶的自动识别与分类。系统首先通过图像预处理获取饮料


spring-ai-starter-mcp-server-webmvc的包冲突
山塘小鱼儿2026/6/27

搭建spring-ai的mcp服务,引用官网的包 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://m


斥资500元/上亿Token,深度横评4个顶尖模型的真实排名~
AI袋鼠帝2026/6/18

大家好,我是袋鼠帝。 6月,感觉又是模型爆发的月份。 前有MiniMax-M3,然后是Claude Fable 5,到Kimi 2.7-code、GLM-5.2,麻了。 我现在都不想看模型的各种榜单、跑分了,感觉有很多刷榜的嫌疑。 而且,每次我测新模型,都有很多朋友在评论区比较其他模型。 毛选说的好,没有调查就没有发言权,实践是检验真理的唯一标准! 这次就来给大家做个顶级模型横测吧 看了下,kimi最新模型主要是编程能力强,这次我想测多个维度。GLM-5.2的Coding Plan暂时没抢到。。


警惕供应链陷阱:从 Red Hat npm 恶意包事件看依赖安全防护
在水一缸2026/6/10

警惕供应链陷阱:从 Red Hat npm 恶意包事件看依赖安全防护 在现代软件开发的宏大叙事中,开源供应链安全已经成为最惊心动魄的章节之一。近期,安全社区爆出的一起针对 Red Hat Cloud Services 的恶意 npm 包事件,再次为我们敲响了警钟。这不仅仅是一次简单的安全通报,它揭示了当前软件供应链攻击手段的隐蔽性与危害性正在不断升级。 对于中级开发者而言,理解这类攻击的底层逻辑、掌握识别恶意包的技巧以及建立系统性的防御思维,已成为职场进阶的必修课。本文将深入剖析这一事件的攻击原


【最新Codex教程】 | 安装、入门和快速使用,适合新手
呆呆敲代码的小Y2026/6/3

前言 🕹️【最新Codex教程】 | 安装、入门和快速使用,适合新手🧐一、 Codex 简介🚀二、安装方法2.1 安装Codex CLI2.2 安装Codex桌面端(推荐) 🎈三、Codex CLI🧑‍💻四、Codex 桌面端4.1 设置页面(语言、宠物、个性化等)4.2 布局区域4.3 工作区管理4.4 添加插件和技能(重要)4.5 配置模型,计划模式和追求目标4.6 权限管理 ✈️五、 账户与订阅💕六、使用技巧6.1 Codex中一直Reconnectin


Agent系列(七):知识库集成——Agent 调用 RAG 的正确姿势
冬奇Lab2026/5/28

RAG 遇上 Agent,不只是"给 LLM 接个搜索框" 很多人第一次接触 RAG,都是这个用法:用户问一个问题 → 检索知识库 → 把结果塞进 Prompt → LLM 生成回答。 这个模式叫 Pipeline RAG。它有效,但有个根本问题——它不思考。 Pipeline RAG 对每一个问题都执行检索,不管这个问题是问"WonderBot 订阅多少钱"(确实需要查知识库),还是问"Python 列表怎么求平均值"(LLM 自己就知道)。它像一个只会一招的工人:不管手头的活是什么,都先去仓


计算机毕业设计:Python出行数据智能分析与预测平台 Django框架 可视化 数据分析 PyEcharts 交通 深度学习(建议收藏)✅
源码之屋2026/5/5

博主介绍:✌全网粉丝10W+,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业项目实战6年之久,选择我们就是选择放心、选择安心毕业✌ > 🍅想要获取完整文章或者源码,或者代做,拉到文章底部即可与我联系了。🍅 点击查看作者主页,了解更多项目! 🍅感兴趣的可以先收藏起来,点赞、关注不迷路,大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,希望帮助同学们顺利毕业 。🍅 1、毕业设计:2026年计算机专业毕业设计选题汇总(建议收藏)✅ 2、大数据毕业


OceanBase学习
摇曳的精灵2026/4/26

OceanBase(OB)是蚂蚁集团完全自研的原生分布式关系型数据库,2010年诞生,支撑支付宝/双11核心交易,金融级高可用,同时兼容 MySQL 与 Oracle 两种模式,是国产分布式数据库的标杆。 一、核心定位(一句话懂差异) Oracle:集中式商用数据库,闭源,高端硬件,强事务,金融传统核心。达梦DM8:集中式(可选共享存储集群),Oracle 高度兼容,政务/国企信创首选。OceanBase:原生分布式,MySQL/Oracle 双兼容,普通x86服务器,水平扩展,金融互联网核心

首页编辑器站点地图

本站内容在 CC BY-SA 4.0 协议下发布

Copyright © 2026 聚合阅读