第1章 Retrofit串行请求的概念与业务场景

串行请求是指多个网络请求按照严格的先后顺序依次发起:前一个请求成功并获得响应数据后,下一个请求才启动执行。这种“一个接一个”的调用模式在首屏加载中直接影响用户等待体验。

1.1 串行请求定义

在Android网络层中,串行请求意味着每条网络任务依赖上一条的结果或条件,请求链条不可并行。与之相对的是并行请求(同时发起多个独立请求)。串行请求的典型特征包括:

  • 依赖链:请求B必须使用请求A的响应数据
  • 顺序保证:先完成的请求不会导致后续请求提前执行
  • 阻塞效应:前一个请求的延迟会累积到总加载时间
对比维度 串行请求 并行请求
请求启动顺序 逐条发起,后一条依赖前一条 全部同时发起
首屏总耗时 各请求耗时之和 耗时最长的请求时间
结果独立 后请求需要前请求数据 各请求无数据依赖
错误传播 一个失败则整个链条中断 单个失败不影响其他

1.2 首屏关键请求链

首屏加载通常包含关键请求链(Critical Request Chain):用户从点击到看见完整UI必须完成的网络请求序列。串行请求形成的链条越长,首屏白屏时间越明显。常见的关键请求链长度在2~4个层级,例如:

  • 获取 → 获取用户基础信息 → 获取首页数据
  • 设备注册 → 获取配置版本 → 下载远程配置
首屏优化临界点:如果一个串行链的总耗时超过1.5秒,用户感知为“等待”;超过3秒流失率会急剧上升。

1.3 典型场景:登录后拉数据

这是最常见的串行依赖场景。用户登录成功后,必须用返回的access_或user_id去请求后续的首页数据。代码实现如下(使用Retrofit + 协程模拟串行):

// 定义两个API接口
interface AuthApi {
    @POST("login")
    suspend fun login(@Body credentials: LoginRequest): LoginResponse
}
interface HomeApi {
    @GET("home")
    suspend fun getHomeData(@Header("Authorization") : String): HomeResponse
}

// 串行调用(协程内)
suspend fun loadHomeScreen() {
    // 请求1:登录
    val loginResponse = authApi.login(LoginRequest("user", "pass"))
    // 请求2:使用登录返回的请求首页
    val homeResponse = homeApi.getHomeData("Bearer ${loginResponse.accessToken}")
    // 绑定UI
    bindHomeView(homeResponse)
}

另一个典型场景是依赖接口:B接口的参数需要从A接口的响应中提取。例如先获取城市列表,再根据选中城市获取天气信息。这类场景中,如果串行链条过长或单个接口超时,会明显拖慢首屏加载。

1.4 串行请求链结构图

串行请求链流程图 串行请求链结构(登录后拉数据) 步骤1: 用户登录 步骤2: 获取 步骤3: 请求首页 依赖关系:步骤2需要使用步骤1返回的,步骤3需要使用步骤2的access_ 总耗时 = 步骤1耗时 + 步骤2耗时 + 步骤3耗时(无法并行) ⚠️ 首屏影响:每条请求延迟累加 建议:尽量将非依赖接口并行化,压缩串行链长度
关键认知:串行请求的“首屏影响”本质上是依赖导致的顺序阻塞。理解这一概念是后续优化(如请求合并、缓存预加载、关键路径压缩)的基础。