news 2026/5/14 12:01:04

Retrofit + Kotlin 协程(Android 实战教程)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Retrofit + Kotlin 协程(Android 实战教程)

Retrofit + Kotlin 协程(Android 实战教程)

这是 Android 开发里最主流的网络请求方案:

Retrofit + Coroutines + MVVM

现代 Android 项目基本都这么写。

这一篇会从:

  • Retrofit 基础
  • suspend 网络请求
  • 协程切线程
  • MVVM 实战
  • 错误处理
  • Flow 配合
  • 封装最佳实践

一路讲到项目级写法。


一、Retrofit 是什么?

Retrofit 是 Square 出的网络请求库。

作用:把 HTTP API 变成 Kotlin 接口

以前Retrofit 之后
HttpURLConnection / OkHttpapi.getUser()
非常麻烦直接像调用本地函数

二、Retrofit 为什么和协程绝配?

以前 Retrofit:

Call.enqueue()

回调地狱:

api.getUser().enqueue(...)

协程之后:

valuser=api.getUser()

像同步代码。但底层仍然是异步。

这就是suspend + Retrofit的威力。


三、添加依赖

// Retrofitimplementation"com.squareup.retrofit2:retrofit:2.11.0"implementation"com.squareup.retrofit2:converter-gson:2.11.0"// 协程implementation"org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1"// ViewModelimplementation"androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.0"implementation"androidx.lifecycle:lifecycle-runtime-ktx:2.8.0"

四、Retrofit 基础配置


五、创建 Data 类

dataclassUser(valid:Int,valname:String)

六、创建 API 接口

这是 Retrofit 核心。

interfaceApiService{@GET("user")suspendfungetUser():User}

重点:suspend

Retrofit 会自动支持协程。


七、创建 Retrofit

objectRetrofitManager{valapi:ApiServicebylazy{Retrofit.Builder().baseUrl("https://example.com/").addConverterFactory(GsonConverterFactory.create()).build().create(ApiService::class.java)}}

八、第一个协程网络请求

ViewModel

classUserViewModel:ViewModel(){funloadUser(){viewModelScope.launch{valuser=RetrofitManager.api.getUser()println(user.name)}}}

九、为什么 suspend 不需要 enqueue?

以前现在
enqueue(callback)suspend fun

Retrofit 内部已经帮你做了:

  • 异步线程
  • Continuation.resume()

这就是协程适配器。


十、Retrofit + Continuation 原理

你写:

suspendfungetUser():User

Retrofit 底层其实拿到了:Continuation<User>

网络返回后:continuation.resume(user),协程恢复。


十一、为什么不会阻塞主线程?

很多人疑惑:

viewModelScope.launch{api.getUser()// 不是在 Main 线程吗?}

为什么不卡 UI?

因为:Retrofit 内部自动切到 OkHttp 线程池,网络完成后再恢复协程。

所以:你看起来像同步,实际上是异步。


十二、withContext 什么时候需要?

Retrofit 请求本身

不需要withContext(IO),因为 Retrofit 已经异步。

但 JSON 大解析需要

valresult=withContext(Dispatchers.Default){parseBigJson()}

数据库操作

withContext(Dispatchers.IO)

十三、POST 请求

API

interfaceApiService{@POST("login")suspendfunlogin(@Bodybody:LoginRequest):LoginResponse}

Request

dataclassLoginRequest(valusername:String,valpassword:String)

十四、Query 参数

@GET("user")suspendfungetUser(@Query("id")id:Int):User// 请求:/user?id=1

十五、Path 参数

@GET("user/{id}")suspendfungetUser(@Path("id")id:Int):User// 请求:/user/1

十六、错误处理(非常重要)

很多人项目里直接崩。正确写法:

viewModelScope.launch{try{valuser=api.getUser()}catch(e:Exception){e.printStackTrace()}}

十七、为什么会抛异常?

Retrofit 协程:网络失败会直接throw Exception,而不是onFailure()


十八、项目级错误封装(推荐)

ResultState

sealedclassResultState<outT>{dataclassSuccess<T>(valdata:T):ResultState<T>()dataclassError(valmsg:String):ResultState<Nothing>()objectLoading:ResultState<Nothing>()}

十九、统一请求封装

suspendfun<T>safeApiCall(apiCall:suspend()->T):ResultState<T>{returntry{ResultState.Success(apiCall())}catch(e:Exception){ResultState.Error(e.message?:"未知错误")}}

二十、使用方式

viewModelScope.launch{when(valresult=safeApiCall{api.getUser()}){isResultState.Success->{// 处理成功}isResultState.Error->{// 处理错误}else->{}}}

二十一、Repository 层(MVVM核心)

现代 Android必须分层


二十二、Repository

classUserRepository{suspendfungetUser():User{returnRetrofitManager.api.getUser()}}

二十三、ViewModel

classUserViewModel:ViewModel(){privatevalrepository=UserRepository()funload(){viewModelScope.launch{valuser=repository.getUser()}}}

二十四、为什么需要 Repository?

因为 ViewModel 不应该直接操作 Retrofit,否则:

  • 耦合严重
  • 不好测试
  • 难维护

二十五、Flow + Retrofit(现代方案)

这是现在最推荐的。

Repository

classUserRepository{fungetUser()=flow{emit(ResultState.Loading)try{valuser=api.getUser()emit(ResultState.Success(user))}catch(e:Exception){emit(ResultState.Error("请求失败"))}}}

ViewModel

funloadUser(){viewModelScope.launch{repository.getUser().collect{// 处理状态}}}

二十六、Flow 的优势

比 suspend 更适合:

  • UI状态
  • Loading
  • 连续数据
  • 重试
  • 分页

二十七、Retrofit + OkHttp

Retrofit 底层其实是OkHttp


二十八、添加日志拦截器

依赖

implementation"com.squareup.okhttp3:logging-interceptor:4.12.0"

配置

vallogging=HttpLoggingInterceptor()logging.level=HttpLoggingInterceptor.Level.BODY

二十九、OkHttpClient

valclient=OkHttpClient.Builder().addInterceptor(logging).build()

三十、Retrofit 使用 client

Retrofit.Builder().client(client)

三十一、拦截器(项目必会)

Token 拦截器

classTokenInterceptor:Interceptor{overridefunintercept(chain:Interceptor.Chain):Response{valrequest=chain.request().newBuilder().addHeader("token","xxx").build()returnchain.proceed(request)}}

三十二、超时设置

OkHttpClient.Builder().connectTimeout(10,TimeUnit.SECONDS).readTimeout(10,TimeUnit.SECONDS)

三十三、协程取消与 Retrofit

这是高频面试题。

当协程 cancel 时,Retrofit 会自动取消网络请求。

因为:Retrofit 协程和 Job 已关联。


三十四、真正的项目结构(推荐)

ui/ viewmodel/ repository/ network/ model/

三十五、标准企业级结构

层级职责
ApiService定义网络接口
RetrofitManagerRetrofit 配置管理
Repository数据仓储,隔离网络层
ViewModel业务逻辑,UI状态管理
UIActivity / Fragment / Compose

三十六、Compose + Retrofit

在 Jetpack Compose 中:

LaunchedEffect(Unit){viewModel.load()}

ViewModel:viewModelScope.launch

这是现代 Android 官方方案。


三十七、Retrofit 常见面试题

1. suspend 为什么不阻塞?

因为:Retrofit 底层OkHttp异步+Continuation恢复

2. Retrofit 为什么不需要 withContext(IO)?

因为:Retrofit 已经异步

3. Retrofit 底层是谁?

Retrofit ↓ OkHttp

4. 协程取消为什么能取消请求?

因为:Coroutine Job关联OkHttp Call.cancel()

5. suspend 本质是什么?

编译器:Continuation + 状态机


三十八、现代 Android 最推荐写法

ViewModel

classUserViewModel:ViewModel(){valuiState=MutableStateFlow<ResultState<User>>(ResultState.Loading)funloadUser(){viewModelScope.launch{uiState.value=ResultState.Loading uiState.value=try{ResultState.Success(api.getUser())}catch(e:Exception){ResultState.Error("失败")}}}}

三十九、真正的大脑模型

以后看到suspend fun getUser(),你脑子里应该自动出现:

Retrofit ↓ OkHttp异步请求 ↓ Continuation挂起 ↓ 网络返回 ↓ resume恢复协程 ↓ 继续执行

四十、总结

组件作用
RetrofitHTTP → Kotlin 接口
suspend协程挂起 + 异步
OkHttp底层网络执行
Repository隔离网络层
ViewModel状态管理与业务逻辑
StateFlow / FlowUI状态响应
ResultState统一错误处理

四十一、企业级最佳实践(非常重要)

不要这样

Activity->Retrofit

要这样

UI ↓ ViewModel ↓ Repository ↓ Retrofit

最后一句(真正理解 Retrofit + 协程)

Retrofit + 协程真正厉害的地方:

不是“代码变短”。

而是:

把异步回调变成了同步思维

底层:

Continuation + 状态机 + OkHttp异步

上层:

像写同步代码一样写异步

这就是现代 Android 网络架构的核心。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/14 12:00:29

FlowPilot:AI Agent工作流引擎如何实现全自动软件开发

1. 项目概述与核心价值 如果你和我一样&#xff0c;每天都要和AI助手&#xff08;比如Claude Code、Cursor、Codex&#xff09;打交道&#xff0c;把需求拆成一个个小任务&#xff0c;然后手动指挥它们写代码、改Bug、跑测试&#xff0c;最后还得自己整理提交&#xff0c;那你肯…

作者头像 李华
网站建设 2026/5/14 11:58:56

纪元1800模组加载器:从零开始打造你的个性化游戏世界

纪元1800模组加载器&#xff1a;从零开始打造你的个性化游戏世界 【免费下载链接】anno1800-mod-loader The one and only mod loader for Anno 1800, supports loading of unpacked RDA files, XML merging and Python mods. 项目地址: https://gitcode.com/gh_mirrors/an/a…

作者头像 李华
网站建设 2026/5/14 11:56:23

SiC双向车载充电器技术解析与V2G应用

1. SiC双向车载充电器的技术革新碳化硅(SiC)功率器件正在彻底改变电动车充电系统的设计范式。与传统硅基器件相比&#xff0c;SiC MOSFET具有三大颠覆性优势&#xff1a;击穿电场强度是硅的10倍&#xff0c;允许更薄的漂移层设计&#xff1b;热导率高达490W/(mK)&#xff0c;是…

作者头像 李华
网站建设 2026/5/14 11:54:14

从力场选择到结果分析:Forcite模拟表面吸附的避坑指南与实战心得

从力场选择到结果分析&#xff1a;Forcite模拟表面吸附的避坑指南与实战心得 在材料模拟领域&#xff0c;表面吸附研究是连接基础理论与工业应用的重要桥梁。当我们使用Materials Studio的Forcite模块进行物理吸附模拟时&#xff0c;往往会遇到一个令人困惑的现象&#xff1a;按…

作者头像 李华