这是一个非常核心且重要的主题,几乎所有的 Android App 都需要与服务器进行通信。

核心交互流程
无论使用哪种技术,Android 与服务器数据交互的基本流程都遵循经典的 客户端-服务器模型:
- 客户端发起请求:Android App (客户端) 根据用户操作或业务逻辑,构建一个请求。
- 网络传输:请求通过 HTTP/HTTPS 协议,经由网络(通常是互联网)发送到服务器。
- 服务器处理:服务器接收到请求后,进行相应的业务处理(如查询数据库、计算逻辑等)。
- 服务器返回响应:服务器将处理结果打包成响应数据(通常是 JSON 或 XML 格式),再通过网络返回给 Android 客户端。
- 客户端处理响应:Android 客户端接收到响应数据,解析后更新 UI 或进行后续操作。
关键技术选型
在 Android 端,主要有三种主流的数据交互方式:
HttpUrlConnection (传统方式)
这是 Java 标准库自带的 HTTP 客户端,非常轻量级,无需额外依赖。
- 优点:
- 无需引入第三方库,是 Android SDK 的一部分。
- 稳定可靠,适合简单的网络请求。
- 缺点:
- API 繁琐:需要手动管理输入流、输出流,代码量多。
- 功能有限:高级功能(如文件上传、下载管理)需要自己实现。
- 同步模型为主:在主线程(UI 线程)中执行会导致应用卡死(ANR),必须手动创建子线程处理网络逻辑,再通过
Handler切换回主线程更新 UI,代码复杂。
- 适用场景:
- 简单的 App 或学习网络编程基础。
- 对第三方库有严格限制的项目。
注意:在大多数现代 Android 开发中,已不推荐直接使用
HttpUrlConnection,除非有特殊需求。(图片来源网络,侵删)
Apache HttpClient (已废弃)
曾经非常流行,但自 Android 6.0 (API 23) 起,org.apache.http 包已被官方完全移除,虽然可以通过 Gradle 引入兼容库,但官方不推荐使用。
请勿在新项目中使用。
OkHttp (现代标准)
Android 开发中最流行、最推荐的 HTTP 客户端,由 Square 公司(著名的开源公司)开发。
- 优点:
- 高效:默认支持 HTTP/2,允许同一主机上的多个请求共享一个 socket,减少延迟。
- 功能强大:支持异步/同步请求、文件上传下载、GZIP 压缩、缓存机制、连接池等。
- API 简洁:相比
HttpUrlConnection,API 设计更现代化,易于使用。 - 与 Retrofit 无缝集成:是 Retrofit 的底层网络实现,是现代 Android 网络请求的黄金搭档。
- 缺点:
需要通过 Gradle 引入依赖。
(图片来源网络,侵删) - 适用场景:
- 所有现代 Android App 的首选。
Retrofit (推荐用于 RESTful API)
Retrofit 本身不是一个网络请求库,它是一个 类型安全的 HTTP 客户端,它基于 OkHttp,通过注解将 Java 接口“翻译”成网络请求。
-
工作原理: 你定义一个 Java 接口,用注解(如
@GET,@POST,@Path,@Query,@Body)来描述 API 的请求方式、路径、参数等,Retrofit 会根据这个接口生成一个实现类,你调用接口方法,Retrofit 就会自动通过 OkHttp 发起网络请求。 -
优点:
- 类型安全:编译时就能检查出 URL 拼写错误、参数类型错误等问题。
- 代码简洁:将网络请求的配置与业务逻辑分离,代码非常清晰、易于维护。
- 支持多种数据解析器:可以轻松集成 Gson, Moshi, Jackson 等库,自动将 JSON 响应解析成 Java 对象(POJO)。
- 支持 RxJava, Coroutines:可以完美配合响应式编程和协程,实现异步操作,代码优雅。
-
依赖:
implementation 'com.squareup.retrofit2:retrofit'implementation 'com.squareup.retrofit2:converter-gson'(用于 JSON 解析)implementation 'com.squareup.okhttp3:logging-interceptor'(用于打印网络日志,调试神器)
数据格式
服务器和客户端之间需要一种“共同语言”来交换数据,最常用的是 JSON。
-
JSON (JavaScript Object Notation):
- 优点:轻量级、易于人阅读和编写、易于机器解析和生成,是目前 Web 和移动端的事实标准。
- 示例:
{ "userId": 1, "name": "张三", "email": "zhangsan@example.com", "isActive": true }
-
XML (eXtensible Markup Language):
- 优点:可扩展性好,有成熟的规范(如 SOAP)。
- 缺点:比 JSON 冗长,解析更复杂,在一些老旧的企业级系统中可能还会用到。
除非有特殊要求,否则请优先选择 JSON。
实战:使用 Retrofit + OkHttp + Gson 实现数据交互
这是目前最主流、最推荐的组合,下面我们通过一个“获取用户信息”的例子来演示完整流程。
添加依赖 (build.gradle (Module: app))
// 1. OkHttp (Retrofit 的底层依赖) implementation 'com.squareup.okhttp3:okhttp:4.11.0' implementation 'com.squareup.okhttp3:logging-interceptor:4.11.0' // 用于日志 // 2. Retrofit implementation 'com.squareup.retrofit2:retrofit:2.9.0' // 3. JSON 解析器 (Gson) implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
添加网络权限 (AndroidManifest.xml)
<uses-permission android:name="android.permission.INTERNET" />
创建数据模型类 (POJO)
根据服务器返回的 JSON 结构,创建对应的 Java/Kotlin 类。
// User.kt
data class User(
val userId: Int,
val name: String,
val email: String
)
创建 API 接口
定义一个接口,用 Retrofit 注解来描述 API。
import retrofit2.Call
import retrofit2.http.GET
import retrofit2.http.Path
// 定义 API 的基础路径
const val BASE_URL = "https://jsonplaceholder.typicode.com/"
interface ApiService {
// GET 请求,路径为 users/{id}
// {id} 是一个路径参数,由 @Path 注解提供
@GET("users/{id}")
fun getUser(@Path("id") userId: Int): Call<User>
}
创建 Retrofit 实例并进行网络请求
在 Activity 或 ViewModel 中发起请求。
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 1. 创建 Retrofit 实例
val retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create()) // 添加 Gson 转换器
.build()
// 2. 创建 API Service 的实现
val apiService = retrofit.create(ApiService::class.java)
// 3. 创建请求 Call
val call = apiService.getUser(1) // 获取 ID 为 1 的用户
// 4. 异步执行请求 (在子线程中)
call.enqueue(object : retrofit2.Callback<User> {
// 请求成功回调
override fun onResponse(call: Call<User>, response: retrofit2.Response<User>) {
if (response.isSuccessful) {
val user = response.body()
if (user != null) {
// 在主线程更新 UI
runOnUiThread {
textView.text = "用户名: ${user.name}\n邮箱: ${user.email}"
}
}
} else {
// 服务器返回了错误码,如 404, 500 等
Log.e("Retrofit", "请求失败: ${response.code()}")
}
}
// 请求失败回调 (如网络连接超时、解析错误等)
override fun onFailure(call: Call<User>, t: Throwable) {
Log.e("Retrofit", "请求异常: ${t.message}")
}
})
}
}
重要注意事项与最佳实践
-
禁止在主线程进行网络请求 Android 的主线程(UI 线程)用于处理用户交互和界面更新,任何耗时操作(包括网络请求)都不能在主线程执行,否则会导致应用卡顿,甚至出现 ANR (Application Not Responding) 错误。
- 解决方案:使用
Thread,AsyncTask(已废弃),HandlerThread, 或更现代的 Kotlin Coroutines 和 RxJava 来处理异步逻辑,Retrofit 的enqueue()方法内部已经处理了线程切换,回调在主线程执行。
- 解决方案:使用
-
处理网络状态 在发起请求前,最好检查设备的网络连接状态。
fun isNetworkConnected(context: Context): Boolean { val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager val activeNetworkInfo = connectivityManager.activeNetworkInfo return activeNetworkInfo != null && activeNetworkInfo.isConnected } -
数据安全 (HTTPS) 所有涉及敏感数据(如用户名、密码、Token)的请求,必须使用
HTTPS协议,以确保数据在传输过程中是加密的,防止中间人攻击。 -
错误处理 网络请求可能会因为各种原因失败(无网络、服务器宕机、参数错误等),代码中必须妥善处理
onFailure和onResponse中的非成功状态(如response.code() == 404),并向用户友好的提示。 -
架构设计 将网络请求逻辑放在专门的 Repository (仓库) 层,而不是直接放在 Activity/Fragment 中,这样可以让 UI 层更“薄”,专注于展示数据,而业务逻辑和数据获取则由 Repository 和 ViewModel (MVVM) 或 Presenter (MVP) 来处理,使代码结构更清晰、更易于测试。
UI (Activity/Fragment) ↓ ViewModel ↓ Repository (负责调用 Retrofit) ↓ Retrofit API Service ↓ Server -
数据缓存 对于不经常变化的数据(如配置信息、文章列表),可以引入缓存机制,OkHttp 本身就支持缓存,Retrofit 也可以配合其他缓存库(如
Room)来实现更复杂的本地缓存策略,以减少网络请求,提升用户体验和离线可用性。
| 技术 | 角色 | 优点 | 缺点 | 推荐度 |
|---|---|---|---|---|
| HttpUrlConnection | 底层 HTTP 客户端 | 无需依赖,轻量 | API 繁琐,功能弱 | ⭐⭐ (仅学习或简单场景) |
| OkHttp | 现代 HTTP 客户端 | 高效,功能全面,支持 HTTP/2 | 需要依赖 | ⭐⭐⭐⭐⭐ (必备) |
| Retrofit | REST API 抽象层 | 类型安全,代码简洁,易于维护 | 需要依赖,学习成本 | ⭐⭐⭐⭐⭐ (与 OkHttp 组合使用) |
对于任何新的 Android 项目,Retrofit + OkHttp + Gson/Kotlinx Serialization 是进行服务器数据交互的黄金标准组合,它高效、强大且能帮助你构建出结构清晰、易于维护的代码。

