为什么 Android App 需要网络?
在开始之前,我们先明确网络功能对 App 的重要性:

- 数据获取:从服务器获取最新信息,如新闻、社交媒体动态、股票行情等。
- 用户认证:登录、注册、验证码等,需要与后端服务器交互。
- 内容同步:在多台设备间同步用户数据,如云笔记、相册同步。
- 实时通信:即时通讯、在线游戏、聊天室等。
- 文件上传/下载:用户上传头像、文件,或下载 App 资源、更新包。
Android 网络通信的演进史
了解历史有助于理解现状和未来趋势。
| 时代/技术 | 描述 | 特点 |
|---|---|---|
| HttpURLConnection (上古时代) | Java 标准库提供的 HTTP 客户端。 | 功能简单,API 略显繁琐,阻塞式。 |
| Apache HttpClient (过去主流) | 功能强大的第三方 HTTP 客户端。 | 功能全面,但体积较大,API 过于复杂。 |
| Volley (Google 推荐的异步库) | 2025 年 I/O 大会推出,专为网络优化。 | 适合数据量小、通信频繁的场景(如加载 JSON),不适合大文件下载。 |
| OkHttp (现代标准) | Square 公司出品,Android 网络的事实标准。 | 高效、简洁、支持 HTTP/2、连接池、拦截器等。 |
| Retrofit (现代标准) | Square 公司出品,基于 OkHttp 的类型安全 HTTP 客户端。 | 将网络请求接口化,通过注解定义 API,极大地简化了网络请求代码。 |
| Jetpack Compose + Kotlin Coroutines/Flow (未来趋势) | Google 推荐的新一代 UI 框架和协程。 | 声明式 UI 与响应式数据流(Flow)完美结合,是构建现代网络 App 的最佳实践。 |
在今天的 Android 开发中,OkHttp + Retrofit 是最主流、最强大的组合,对于新项目,特别是使用 Jetpack Compose 的,Kotlin Coroutines + Retrofit + Flow 是首选。
核心概念与基础
在深入代码之前,必须理解几个关键概念。
网络协议栈
- TCP/IP:互联网的基石协议,它确保了数据包能够可靠、有序地从发送方传输到接收方,OkHttp 和 Retrofit 都构建在 TCP/IP 之上。
- HTTP/HTTPS:应用层协议,用于在 Web 浏览器和服务器之间传输数据。
- HTTP:超文本传输协议,数据是明文传输的,不安全。
- HTTPS:HTTP over SSL/TLS,在 HTTP 的基础上加入了加密层,保证了数据传输的机密性和完整性。所有现代 App 都必须使用 HTTPS。
网络请求与响应
一个典型的网络交互过程如下:

- 客户端(你的 App)向 服务器 发送一个 请求。
- 请求 包含:请求方法、请求头、请求体。
- 服务器 接收请求,处理后返回一个 响应。
- 响应 包含:响应状态码、响应头、响应体。
请求方法:
GET:获取数据,最常用的方法,参数通常跟在 URL 后面。POST:提交数据,通常用于提交表单、上传文件等,数据放在请求体中。PUT/PATCH:更新数据。PUT通常用于完全替换,PATCH用于部分更新。DELETE:删除数据。
响应状态码:
2xx(成功):200 OK(成功),201 Created(创建成功)。3xx(重定向):301 Moved Permanently(永久重定向)。4xx(客户端错误):400 Bad Request(请求错误),401 Unauthorized(未授权),404 Not Found(资源不存在)。5xx(服务器错误):500 Internal Server Error(服务器内部错误)。
线程模型
这是 Android 网络开发中最重要的一点!
Android 的 UI 线程(主线程)是负责绘制界面和处理用户交互的。任何耗时操作(包括网络请求)都不能在主线程中执行,否则会导致应用 ANR (Application Not Responding)。

解决方案:
- 传统方式:使用
AsyncTask、Thread+Handler,这些方式已被废弃或使用复杂,不推荐。 - 现代方式:使用 Kotlin Coroutines 或 RxJava,它们能以更简洁、更安全的方式处理异步任务。
主流网络库实战
OkHttp + Retrofit (经典组合)
这是目前最流行、最成熟的方案。
添加依赖
在 app/build.gradle 文件中添加:
// OkHttp
implementation("com.squareup.okhttp3:okhttp:4.12.0") // 使用最新版本
// Retrofit
implementation("com.squareup.retrofit2:retrofit:2.9.0") // 使用最新版本
implementation("com.squareup.retrofit2:converter-gson:2.9.0") // Gson 解析器
implementation("com.squareup.retrofit2:converter-moshi:2.9.0") // Moshi 解析器
implementation("com.squareup.retrofit2:adapter-rxjava3:2.9.0") // RxJava 3 适配器 (可选)
implementation("com.squareup.retrofit2:adapter-coroutines:0.9.2") // Coroutines 适配器 (可选)
定义数据模型
使用 data class 来定义服务器返回的 JSON 数据结构。
// User.kt
data class User(
val id: Int,
val name: String,
val email: String
)
// API 响应的通用结构
data class ApiResponse<T>(
val code: Int,
val message: String,
val data: T
)
创建 Retrofit 实例并定义 API 接口
// ApiService.kt
interface ApiService {
// GET 请求示例
@GET("users/{id}")
suspend fun getUser(@Path("id") userId: Int): ApiResponse<User> // 使用 suspend 函数,使其在协程中调用
// POST 请求示例
@POST("users")
suspend fun createUser(@Body user: User): ApiResponse<User>
}
// RetrofitClient.kt (单例模式)
object RetrofitClient {
private const val BASE_URL = "https://api.example.com/v2/" // 替换为你的 API 地址
private val retrofit by lazy {
Retrofit.Builder()
.baseUrl(BASE_URL)
.client(getOkHttpClient()) // 配置 OkHttp
.addConverterFactory(GsonConverterFactory.create()) // 使用 Gson 解析
.addCallAdapterFactory(CoroutinesCallAdapterFactory.create()) // 支持 suspend 函数
.build()
}
private fun getOkHttpClient(): OkHttpClient {
return OkHttpClient.Builder()
.addInterceptor(HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY // 打印日志
})
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.build()
}
val apiService: ApiService by lazy {
retrofit.create(ApiService::class.java)
}
}
在 ViewModel 或协程作用域中调用
最佳实践:在 ViewModel 中使用 viewModelScope
// MyViewModel.kt
class MyViewModel : ViewModel() {
private val _user = MutableLiveData<ApiResponse<User>>()
val user: LiveData<ApiResponse<User>> = _user
fun fetchUser(userId: Int) {
viewModelScope.launch { // viewModelScope 会在 ViewModel 销毁时自动取消
try {
val response = RetrofitClient.apiService.getUser(userId)
_user.value = response
} catch (e: Exception) {
// 处理网络错误
Log.e("MyViewModel", "Network error: ${e.message}")
}
}
}
}
Jetpack Compose + Flow (现代响应式方案)
这个方案将网络请求与 UI 更新无缝结合,代码更简洁。
修改 Retrofit 返回类型为 Flow
Retrofit 本身不直接返回 Flow,但我们可以使用 kotlinx.coroutines.flow.flow 和 retrofit2.Call 来创建。
// ApiService.kt
interface ApiService {
@GET("users/{id}")
fun getUser(@Path("id") userId: Int): Call<ApiResponse<User>> // 返回 Call
// 或者直接返回 Response
@GET("users/{id}")
suspend fun getUserResponse(@Path("id") userId: Int): Response<ApiResponse<User>>
}
在 Repository 中封装网络逻辑并暴露 Flow
Repository 是数据源(网络、本地数据库)和 ViewModel 之间的桥梁。
// UserRepository.kt
class UserRepository {
fun getUser(userId: Int): Flow<ApiResponse<User>> = flow {
try {
// 调用 Retrofit 的 suspend 函数
val response = RetrofitClient.apiService.getUserResponse(userId)
if (response.isSuccessful) {
emit(response.body()!!)
} else {
// 处理错误响应
emit(ApiResponse(code = response.code(), message = "Error: ${response.message()}", data = null))
}
} catch (e: Exception) {
// 处理网络异常
emit(ApiResponse(code = -1, message = "Network Error: ${e.message}", data = null))
}
}.flowOn(Dispatchers.IO) // 在 IO 线程执行
}
在 ViewModel 中收集 Flow 并更新 UI State
// MyViewModel.kt
class MyViewModel(private val userRepository: UserRepository) : ViewModel() {
// 使用 StateFlow 来持有 UI 状态
private val _uiState = MutableStateFlow<UiState>(UiState.Loading)
val uiState: StateFlow<UiState> = _uiState
sealed class UiState {
object Loading : UiState()
data class Success(val user: User) : UiState()
data class Error(val message: String) : UiState()
}
fun fetchUser(userId: Int) {
viewModelScope.launch {
userRepository.getUser(userId)
.collect { response ->
when {
response.data != null -> _uiState.value = UiState.Success(response.data)
else -> _uiState.value = UiState.Error(response.message)
}
}
}
}
}
在 Composable 中观察 StateFlow 并渲染 UI
// MyScreen.kt
@Composable
fun MyScreen(viewModel: MyViewModel = viewModel()) {
val uiState by viewModel.uiState.collectAsState() // 收集 StateFlow 并触发重组
when (val state = uiState) {
is MyViewModel.UiState.Loading -> {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
CircularProgressIndicator()
}
}
is MyViewModel.UiState.Success -> {
Text(text = "Hello, ${state.user.name}!")
}
is MyViewModel.UiState.Error -> {
Text(text = "Error: ${state.message}", color = Color.Red)
}
}
}
高级主题与最佳实践
权限申请
从 Android 9 (API 28) 开始,App 默认使用 HTTPS,如果你的 App 需要使用 HTTP(不推荐),需要在 AndroidManifest.xml 中声明:
<application
...
android:usesCleartextTraffic="true">
...
</application>
对于访问网络,不需要在 AndroidManifest.xml 中申请特殊权限,网络访问是所有 App 的基本功能。
网络状态监听
如何知道当前设备是否有网络?
- ConnectivityManager:这是官方推荐的方式。
fun isNetworkAvailable(context: Context): Boolean {
val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val activeNetwork = connectivityManager.activeNetwork ?: return false
val capabilities = connectivityManager.getNetworkCapabilities(activeNetwork) ?: return false
return capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) ||
capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) ||
capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)
} else {
@Suppress("DEPRECATION")
val networkInfo = connectivityManager.activeNetworkInfo ?: return false
@Suppress("DEPRECATION")
return networkInfo.isConnected
}
}
数据缓存
为了减少网络请求,提升用户体验和节省流量,缓存至关重要。
- HTTP 缓存:OkHttp 内置了基于
Cache-Control响应头的缓存机制,你只需在OkHttpClient中配置一个缓存目录即可。val cache = Cache(context.cacheDir, 10 * 1024 * 1024) // 10 MB val okHttpClient = OkHttpClient.Builder() .cache(cache) .build() - 数据库缓存:对于需要离线访问的数据,通常使用
Room数据库将网络数据持久化到本地。
拦截器
拦截器是 OkHttp 的核心特性,它允许你在请求被发送之前和响应被接收之后对它们进行修改。
- 日志拦截器:
HttpLoggingInterceptor,用于调试。 - Header 拦截器:统一添加请求头,如
Authorization,User-Agent等。val headerInterceptor = Interceptor { chain -> val request = chain.request() .newBuilder() .addHeader("Authorization", "Bearer your_token") .build() chain.proceed(request) } - 重试拦截器:当网络请求失败时自动重试。
安全性
- HTTPS:必须启用。
- 证书锁定:对于金融、支付等高安全要求的 App,可以考虑使用证书锁定,防止中间人攻击。
- 敏感数据:不要在 URL 或日志中打印敏感信息(如密码、Token),使用
@Header注解时,确保服务器使用HTTPS。
总结与学习路径
| 技术栈 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| OkHttp + Retrofit | 成熟、稳定、社区强大、功能全面 | 配置稍多,概念较多 | 绝大多数 App,尤其是传统 View 系统 App |
| Retrofit + Flow | 响应式、与 Jetpack 组件集成度高、代码更简洁 | 需要理解 Flow 和协程 | 所有新项目,特别是 Jetpack Compose App |
| Ktor (Kotlin 官方) | 与 Kotlin 语法完美融合,易于使用 | 相比 Retrofit 生态稍小 | 纯 Kotlin 项目,或需要同时作为客户端和服务端时 |
给初学者的学习建议:
- 先理解基础:搞懂 HTTP 协议、线程模型、JSON。
- 掌握协程:这是现代 Android 开发的基石,必须学会
launch,async,suspend函数、viewModelScope。 - 学习 OkHttp:理解其核心概念,如
Call,Interceptor,Cache。 - 精通 Retrofit:学习如何定义接口、使用注解、集成不同解析器。
- 学习 Jetpack 架构组件:将网络逻辑放在
Repository中,通过ViewModel和LiveData/StateFlow暴露给 UI。 - 拥抱 Compose + Flow:这是未来的方向,尽早学习可以让你保持技术领先。
希望这份详细的指南能帮助你全面了解 Android App 的网络开发!
