核心概念:网络通信基础
在深入 Android 代码之前,理解一些网络基础概念至关重要。

-
HTTP/HTTPS:
- HTTP (HyperText Transfer Protocol): 超文本传输协议,是互联网上应用最广泛的一种网络协议,它定义了客户端(如手机App)和服务器之间如何交换信息。
- HTTPS (HTTP Secure): 安全的HTTP,通过 SSL/TLS 协议对数据进行加密,是现在网络通信的绝对标准,Android 9 (API 28) 开始,默认要求所有网络连接使用 HTTPS。
-
请求与响应:
- 请求: 客户端向服务器发送的数据包,包含:
- 方法:
GET(获取数据),POST(提交数据),PUT(更新数据),DELETE(删除数据) 等。 - URL: 请求的资源地址。
- 请求头: 包含如
Content-Type(数据类型),Authorization(认证信息) 等元数据。 - 请求体: 对于
POST/PUT请求,包含实际要发送的数据(如JSON、表单)。
- 方法:
- 响应: 服务器返回给客户端的数据包,包含:
- 状态码: 如
200 OK(成功),404 Not Found(资源不存在),500 Internal Server Error(服务器错误)。 - 响应头: 包含如
Content-Type(返回数据类型),Content-Length(数据长度) 等。 - 响应体: 服务器返回的实际数据,通常是 JSON 或 XML 格式。
- 状态码: 如
- 请求: 客户端向服务器发送的数据包,包含:
-
数据格式:
- JSON (JavaScript Object Notation): 轻量级的数据交换格式,易于人阅读和编写,也易于机器解析和生成。目前是移动端与服务器通信的事实标准。
- XML (eXtensible Markup Language): 曾经非常流行,但现在因其冗长和解析复杂,在移动端已较少使用。
- Protocol Buffers / gRPC: Google 开发的高性能、语言中立、平台中立的数据序列化框架,适合对性能和效率要求极高的场景。
Android 网络技术演进
Android 提供了多种网络库,从最底层的 HttpURLConnection 到现代化的协程 + Retrofit,经历了巨大的演进。

传统方式:HttpURLConnection 和 HttpClient
-
HttpURLConnection:
-
优点: Android SDK 内置,无需额外依赖,功能稳定。
-
缺点: API 较为繁琐,需要手动管理线程(网络请求不能在主线程执行),处理数据流和解析逻辑需要编写大量样板代码。
-
示例代码:
// 必须在子线程或使用异步任务执行 new Thread(() -> { try { URL url = new URL("https://api.example.com/data"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); InputStream inputStream = connection.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); StringBuilder response = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { response.append(line); } // 在这里解析 response 并更新 UI (需要切回主线程) Log.d("Network", response.toString()); } catch (IOException e) { e.printStackTrace(); } }).start();
-
-
HttpClient:
- 在 Android 6.0 (API 23) 中已被废弃。强烈不建议在新项目中使用。
小结: 这两种方式是基础,但在现代开发中已不直接使用,因为它们太“原始”了。
现代方式:第三方网络库
为了解决原生 API 的问题,社区涌现了许多优秀的第三方库,它们极大地简化了网络开发。
A. OkHttp
- 定位: 一个高效的 HTTP & HTTP/2 客户端。
- 核心优势:
- 高效: 支持HTTP/2、连接池(复用TCP连接)、GZIP压缩。
- 简单易用: 提供了非常简洁的 API。
- 核心功能: 处理同步/异步请求、文件上传下载、缓存、WebSocket。
- 它与 Retrofit 的关系: OkHttp 是 Retrofit 的默认底层网络实现,Retrofit 负责将接口定义转换为具体的网络请求,而 OkHttp 负责执行这个请求。
B. Retrofit
- 定位: 类型安全的 HTTP 客户端。
- 核心优势:
- 接口驱动: 你只需定义一个 Java/Kotlin 接口,并用注解描述 API,Retrofit 会为你生成实现。
- 自动解析: 内置了 Gson, Moshi, Jackson 等解析器,能自动将 JSON 响应体转换成 Java/Kotlin 对象。
- 无缝集成: 与 OkHttp、RxJava、Kotlin Coroutines 完美集成。
- 基本用法:
- 定义 API 接口:
interface ApiService { @GET("users/{user}/repos") suspend fun getRepos(@Path("user") user: String): List<Repo> // 使用协程 } - 创建 Retrofit 实例:
val retrofit = Retrofit.Builder() .baseUrl("https://api.github.com/") .addConverterFactory(GsonConverterFactory.create()) // 使用Gson解析 .build() - 创建接口实例并发起请求:
val apiService = retrofit.create(ApiService::class.java) // 在协程作用域内调用 suspend 函数 val repos = apiService.getRepos("google")
- 定义 API 接口:
- Retrofit + OkHttp + Coroutines: 这是目前 Android 官方推荐 的黄金组合,代码简洁、类型安全、易于维护。
C. 其他库
- Volley: 由 Google 推出的库,适合小数据量的、频繁的请求,内存管理好,但在大文件下载和流式处理方面不如 OkHttp。
- Android Jetpack - WorkManager: 不是一个网络库,而是一个用于确保后台任务(包括网络请求)可靠执行的库,它适用于即使应用退出或重启也需要保证完成的网络任务(如数据同步)。
关键考量与最佳实践
编写网络代码时,必须考虑以下几个方面,这直接关系到 App 的稳定性、性能和用户体验。
线程管理
- 黄金法则: 所有网络请求都不能在主线程(UI线程)中执行,否则会抛出
NetworkOnMainThreadException异常,导致应用卡顿甚至ANR。 - 解决方案:
- 传统:
AsyncTask,Thread+Handler。 - 现代: Kotlin Coroutines (首选) 或
RxJava,它们能以非常简洁的代码处理异步逻辑,避免回调地狱。
- 传统:
数据解析
- 推荐使用 JSON 解析库:
- Gson: Google 开发,非常成熟稳定。
- Moshi: Square 出品,性能更好,对 Kotlin 支持更友好(如默认支持 Kotlin 默认参数)。
- Kotlinx Serialization: Kotlin 官方推出的序列化库,与 Kotlin 语言无缝集成,是未来的趋势。
- Retrofit 会自动集成这些解析器,你只需要在
ConverterFactory中指定即可。
错误处理
- 网络错误: 没有网络连接、DNS 解析失败、服务器无响应等。
- 协议错误: 服务器返回
4xx(客户端错误) 或5xx(服务器错误) 状态码。 - 数据解析错误: 服务器返回的数据格式不符合预期,导致解析失败。
- 最佳实践:
- 使用
try-catch捕获网络和解析异常。 - 根据不同的错误类型向用户展示不同的友好提示。
- 使用 Retrofit 的
Callback或协程的try-catch块来处理 HTTP 状态码错误。
- 使用
安全性
- 使用 HTTPS: 强制所有网络请求使用 HTTPS,防止数据在传输过程中被窃听或篡改。
- 证书锁定: 对于金融、支付等高安全要求的 App,可以考虑使用证书锁定,确保你的 App 只信任你自己的服务器证书,防止中间人攻击。
- 敏感信息保护: 不要在 URL 或日志中硬编码 API Key、Token 等敏感信息,最好在服务端进行权限校验。
性能优化
- 连接池: OkHttp 默认启用连接池,复用 TCP 连接,减少握手开销,提升性能。
- 缓存: OkHttp 和服务器都可以配置缓存策略,减少重复请求,加快加载速度,节省流量。
- 数据压缩: OkHttp 默认支持 GZIP 压缩,可以显著减小传输数据的大小。
代码示例:Retrofit + OkHttp + Coroutines
这是一个完整、现代的 Android 网络请求示例。
添加依赖 (build.gradle.kts / build.gradle)
// build.gradle
dependencies {
// Retrofit & OkHttp
implementation("com.squareup.retrofit2:retrofit:2.9.0")
implementation("com.squareup.retrofit2:converter-gson:2.9.0") // 或 converter-moshi
implementation("com.squareup.okhttp3:logging-interceptor:4.11.0") // 用于日志
// Coroutines
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")
}
添加网络权限 (AndroidManifest.xml)
<uses-permission android:name="android.permission.INTERNET" />
<application
...
android:usesCleartextTraffic="true"> <!-- 如果请求HTTP(不推荐),需要加这个 -->
...
</application>
定义数据模型 (Kotlin)
// data/Repo.kt
data class Repo(
val id: Int,
val name: String,
val full_name: String,
val owner: Owner
)
data class Owner(
val login: String
// ... 其他字段
)
定义 API 接口
// network/ApiService.kt
import retrofit2.http.GET
import retrofit2.http.Path
interface ApiService {
@GET("users/{username}/repos")
suspend fun getRepos(@Path("username") username: String): List<Repo>
}
创建 Retrofit 实例 (单例模式最佳)
// network/RetrofitInstance.kt
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
object RetrofitInstance {
private const val BASE_URL = "https://api.github.com/"
// 创建一个OkHttp客户端,并添加日志拦截器
private val okHttpClient = OkHttpClient.Builder()
.addInterceptor(HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
})
.build()
val api: ApiService by lazy {
Retrofit.Builder()
.baseUrl(BASE_URL)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(ApiService::class.java)
}
}
在 ViewModel 或 Activity/Fragment 中调用
// MyViewModel.kt
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.launch
class MyViewModel : ViewModel() {
fun fetchRepos() {
viewModelScope.launch { // viewModelScope 自动在配置变更时取消协程
try {
val repos = RetrofitInstance.api.getRepos("google")
// 成功,更新 UI
Log.d("ViewModel", "Repos fetched: ${repos.size}")
// _uiState.value = UiState.Success(repos) // 使用 StateFlow 或 LiveData
} catch (e: Exception) {
// 失败,处理错误
Log.e("ViewModel", "Error fetching repos", e)
// _uiState.value = UiState.Error(e.message ?: "Unknown error")
}
}
}
}
未来趋势
- Kotlin Coroutines 成为标准: Google 已明确将协程作为处理异步操作的首选方式,其简洁性和安全性远超传统的回调和 RxJava。
- Kotlin Multiplatform Mobile (KMM): 允许共享业务逻辑(包括网络层代码)在 Android 和 iOS 之间,网络请求的代码可以写在共享模块中,避免重复开发。
- gRPC 的普及: 对于微服务架构,gRPC 因其高性能和强类型定义,正在逐渐取代 REST API,成为服务间通信的新标准。
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| HttpURLConnection | 系统内置,无依赖 | API繁琐,需手动管理线程 | 学习网络原理,或极简项目 |
| Volley | 简单易用,内存管理好 | 不适合大文件,性能一般 | 小数据量、频繁请求的App |
| OkHttp | 高性能,功能强大 | 需要手动解析数据 | 作为 Retrofit 的底层,或需要直接操作网络流时 |
| Retrofit | 类型安全,接口驱动,自动解析 | 依赖 OkHttp | 现代 Android 开发的事实标准 |
| Retrofit + Coroutines | 代码最简洁,可读性高,生命周期管理好 | - | Android 官方和社区最推荐的组合 |
对于任何新的 Android 项目,强烈建议你从 Retrofit + OkHttp + Kotlin Coroutines 这个组合开始,它能让你用最少的代码,写出最健壮、最高效、最易于维护的网络层。
