核心概念:网络通信的基础
在深入 Android 代码之前,有几个核心概念必须理解:

- 协议:网络通信的规则,在 Android 开发中最常见的是 HTTP/HTTPS,HTTPS 是 HTTP 的安全版本,通过 SSL/TLS 加密,是现代 App 的标准。
- URL (Uniform Resource Locator):网络资源的地址。
https://api.example.com/users/123。https: 协议api.example.com: 域名/users/123: 路径
- 请求:客户端(你的 App)向服务器发送数据。
- 请求方法:最常用的是
GET(获取数据)和POST(提交数据)。 - 请求头:附加信息,如
Content-Type类型)、Authorization(认证信息)等。 - 请求体:要发送给服务器的数据,通常用于
POST请求。
- 请求方法:最常用的是
- 响应:服务器收到请求后,返回给客户端的数据。
- 响应状态码:表示请求的结果,如
200 OK(成功)、404 Not Found(资源不存在)、500 Internal Server Error(服务器错误)。 - 响应头:服务器的附加信息。
- 响应体:服务器返回的实际数据,通常是 JSON 或 XML 格式。JSON 是绝对的主流。
- 响应状态码:表示请求的结果,如
Android 网络数据传输演进史
Android 的网络编程方式经历了几个重要的阶段,了解这个演进过程有助于你理解为什么现在推荐使用某些技术。
HttpURLConnection (上古时代)
- 简介:这是 Android SDK 自带的传统 API,非常基础,功能有限。
- 特点:
- 手动管理连接(
setConnectTimeout,setReadTimeout)。 - 手动处理输入输出流。
- 代码冗长,容易出错。
- 默认不处理 GZIP 压缩。
- 在 Android 2.2 (API 8) 之前存在一些 Bug。
- 手动管理连接(
- 现状:不推荐在新项目中使用,除非有极特殊的老旧项目维护需求。
Apache HttpClient (已废弃)
- 简介:功能强大,曾是 Java 生态中非常流行的 HTTP 客户端。
- 特点:
- API 相对完善,功能丰富。
- 在 Android 6.0 (API 23) 中,Google 彻底移除了对它的支持。
- 现状:完全废弃,绝对不要在新项目中使用。
Volley (Google 推荐的“过渡期”方案)
- 简介:Google 在 2025 年 I/O 大会上推出的网络库,旨在解决
HttpURLConnection和HttpClient的痛点。 - 特点:
- 优点:
- 非常适合数据量不大、但频繁通信的场景(如加载图片、JSON 数据)。
- 内置图片加载功能 (
ImageLoader)。 - 请求队列管理,取消请求非常方便。
- 自动解析 JSON。
- 缺点:
- 大文件上传/下载性能不佳。
- 不直接支持
PATCH等不常用的 HTTP 方法。 - 库本身已经很久没有更新。
- 优点:
- 现状:适用于中小型 App,但对于大型或复杂项目,现在有更好的选择。
OkHttp (现代网络请求的基石)
- 简介:Android 和 Java 世界中最流行、最强大的 HTTP & HTTP/2 客户端。
- 特点:
- 高效:支持 HTTP/2,允许同一主机上的所有请求共享一个 socket,极大提升了性能。
- 连接池:复用 TCP 连接,减少握手开销。
- 现代:内置 GZIP 压缩、响应缓存。
- 灵活:拦截器机制是其核心,可以非常方便地实现日志、缓存、认证等功能。
- 简单:API 设计简洁易用。
- 现状:现代 Android 开发的首选网络库,但请注意,OkHttp 本身只负责连接和数据传输,它不直接解析 JSON。
Retrofit (类型安全的 HTTP 客户端)
- 简介:基于 OkHttp 构建的类型安全的 RESTful API 请求库。
- 工作原理:通过接口和注解来定义 API 请求,Retrofit 在运行时动态将这些接口实现为网络调用。
- 特点:
- 类型安全:将 API 端点映射到 Java/Kotlin 接口,编译时就能检查出错误。
- 解耦:网络请求逻辑与业务逻辑完全分离。
- 可扩展:通过 Converter(如 Gson, Moshi)处理 JSON 序列化/反序列化;通过 CallAdapter 处理返回类型(如 RxJava, Coroutines)。
- 生态完善:与 OkHttp、Gson/Moshi、RxJava、Kotlin Coroutines 无缝集成。
- 现状:Android 开发的事实标准,几乎所有的现代商业 App 都在使用 Retrofit + OkHttp 的组合。
现代 Android 网络最佳实践 (Retrofit + OkHttp + Coroutines/Moshi)
下面我们以当前最主流的技术栈为例,讲解如何进行网络数据传输。
添加依赖
在 build.gradle.kts (或 build.gradle) 文件中添加:
// OkHttp: 网络请求的执行者
implementation("com.squareup.okhttp3:okhttp:4.12.0")
// Retrofit: 类型安全的 API 请求封装
implementation("com.squareup.retrofit2:retrofit:2.9.0")
// Kotlin Coroutines Call Adapter: 让 Retrofit 支持 suspend 函数
implementation("com.squareup.retrofit2:converter-scalars:2.9.0") // 先加一个基础的
implementation("com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2") // 旧的,推荐用下面新的
// 或者使用新的, Retrofit 2.6+ 内置了对协程的支持
// implementation("com.squareup.retrofit2:retrofit:2.9.0") // 已经包含了
// Moshi: 高性能的 JSON 解析库 (替代 Gson)
implementation("com.squareup.moshi:moshi:1.15.0")
implementation("com.squareup.moshi:moshi-kotlin:1.15.0") // 支持 Kotlin 默认值等
// Moshi Converter
implementation("com.squareup.retrofit2:converter-moshi:2.9.0")
// OkHttp Logging Interceptor: 方便调试,打印网络请求日志
implementation("com.squareup.okhttp3:logging-interceptor:4.12.0")
创建数据类
根据服务器返回的 JSON 结构,创建对应的 Kotlin 数据类。

// User.kt
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true) // 启用 Moshi 代码生成,性能更好
data class User(
@Json(name = "id") val id: Int,
@Json(name = "name") val name: String,
@Json(name = "email") val email: String
)
// API 响应的通用包装类
data class ApiResponse<T>(
val code: Int,
val message: String,
val data: T // 这里泛型 T 可以是 User, List<User> 等
)
定义 API 接口
使用 Retrofit 的注解来描述你的 API。
import retrofit2.http.*
interface ApiService {
// GET 请求: 获取用户列表
@GET("users")
suspend fun getUsers(): ApiResponse<List<User>>
// GET 请求: 根据 ID 获取单个用户 (路径参数)
@GET("users/{id}")
suspend fun getUserById(@Path("id") userId: Int): ApiResponse<User>
// POST 请求: 创建新用户 (请求体)
@POST("users")
suspend fun createUser(@Body user: User): ApiResponse<User>
// PUT 请求: 更新用户 (路径参数 + 请求体)
@PUT("users/{id}")
suspend fun updateUser(@Path("id") userId: Int, @Body user: User): ApiResponse<User>
}
suspend fun: 表示这个函数可以在协程中挂起执行,Retrofit 会处理其异步逻辑。@GET,@POST: HTTP 方法。@Path: URL 中的路径参数。@Query: URL 中的查询参数 (e.g.,?page=1&size=10)。@Body: 请求体,用于POST/PUT请求。
配置和创建 Retrofit 实例
object RetrofitClient {
private const val BASE_URL = "https://api.example.com/v1/" // 以 /
// 创建 OkHttp 实例
private val okHttpClient = OkHttpClient.Builder()
.addInterceptor(HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY // 打印详细日志
})
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.build()
// 创建 Retrofit 实例
val instance: ApiService by lazy {
Retrofit.Builder()
.baseUrl(BASE_URL)
.client(okHttpClient)
.addConverterFactory(MoshiConverterFactory.create()) // 使用 Moshi 解析 JSON
.build()
.create(ApiService::class.java)
}
}
在 ViewModel 或 Activity/Fragment 中调用
在 ViewModel 中进行网络请求是最佳实践,因为它能更好地处理屏幕旋转等配置变化。
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.launch
class UserViewModel : ViewModel() {
private val _users = MutableLiveData<List<User>>()
val users: LiveData<List<User>> = _users
private val _error = MutableLiveData<String>()
val error: LiveData<String> = _error
fun fetchUsers() {
viewModelScope.launch { // 在协程作用域内发起请求
try {
// Retrofit 会自动将 suspend 函数的调用转换为异步操作
val response = RetrofitClient.instance.getUsers()
if (response.code == 200) {
_users.value = response.data
} else {
_error.value = "Error: ${response.message}"
}
} catch (e: Exception) {
_error.value = "Network Error: ${e.message}"
}
}
}
}
重要注意事项与最佳实践
-
网络权限 在
AndroidManifest.xml中必须声明网络权限:<uses-permission android:name="android.permission.INTERNET" />
从 Android 9 (API 28) 开始,默认情况下,App 的明流量(非 HTTPS)被禁用。强烈建议所有网络请求都使用 HTTPS。
(图片来源网络,侵删) -
在后台线程执行网络请求 绝对不能在主线程(UI 线程)中进行网络请求,否则会抛出
NetworkOnMainThreadException并导致 ANR(应用无响应),使用ViewModel+Coroutines或RxJava可以完美地解决这个问题。 -
数据解析
- JSON: 推荐使用 Moshi 或 Gson,Moshi 对 Kotlin 的支持更好,性能也略优。
- XML: 可以使用
XmlPullParser或第三方库如 Simple XML。 - Protobuf: Google 的高效二进制序列化格式,适合对性能和带宽要求极高的场景。
-
安全性
- HTTPS: 必须使用 HTTPS。
- 证书锁定: 对于金融等高安全级别 App,可以考虑使用证书锁定,防止中间人攻击。
- 敏感数据: 不要在 URL 或日志中打印敏感信息(如 Token、密码),使用 OkHttp 的
Interceptor可以方便地过滤日志。
-
错误处理
- 处理 HTTP 错误(如 404, 500)。
- 处理网络异常(如无网络、超时)。
- 处理数据解析异常(如 JSON 格式错误)。
- 向用户友好的展示错误信息。
-
数据缓存
- OkHttp 缓存: OkHttp 自带了一个基于 DiskLruCache 的响应缓存,你可以通过
Cache类来配置它。 - 离线优先: 一种常见的策略是先检查本地缓存,如果有且未过期,则直接返回缓存数据;否则再发起网络请求,成功后再更新缓存。
- OkHttp 缓存: OkHttp 自带了一个基于 DiskLruCache 的响应缓存,你可以通过
-
依赖注入 对于大型项目,推荐使用 Hilt 或 Koin 等依赖注入框架来管理 Retrofit、OkHttp、ViewModel 等单例对象,使代码更整洁、易于测试。
| 技术 | 角色 | 优点 | 适用场景 |
|---|---|---|---|
| OkHttp | 网络引擎 | 高性能(HTTP/2, 连接池)、灵活(拦截器) | 所有需要网络通信的 App 的底层基础 |
| Retrofit | API 封装器 | 类型安全、解耦、易用 | 定义和调用 RESTful API 的标准方式 |
| Moshi/Gson | JSON 解析器 | 将 JSON 字符串与对象互转 | 处理网络请求/响应的 JSON 数据 |
| Kotlin Coroutines | 异步编程 | 代码简洁、结构清晰、生命周期感知 | 现代 Android 开发的首选异步方案 |
推荐的现代 Android 网络架构:
ViewModel + Kotlin Coroutines -> Retrofit -> OkHttp -> Moshi -> Server
这个组合提供了类型安全、高性能、易于维护和扩展的完整解决方案,是当前业界的主流和最佳实践。
