目录
-
核心概念:Android 网络通信基础
(图片来源网络,侵删)- 主线程限制 (NetworkOnMainThreadException)
- 网络权限
- HTTPS 与安全
-
使用原生
HttpURLConnection(官方推荐,基础)- 特点
- GET 请求示例
- POST 请求示例
-
使用第三方库
OkHttp(强烈推荐,现代标准)- 特点
- GET 请求示例
- POST 请求示例 (发送 JSON)
-
使用第三方库
Retrofit(高级,面向接口)- 特点
- 设置步骤
- 完整示例
-
后台执行网络请求
(图片来源网络,侵删)- 使用
Coroutine(Kotlin, 现代) - 使用
AsyncTask(Java, 已废弃,但为了完整性提及)
- 使用
-
解析服务器响应
- 手动解析 (JSON)
- 使用
Gson/Moshi自动解析
-
最佳实践与总结
核心概念:Android 网络通信基础
在开始写代码前,必须了解几个关键点。
a. 主线程限制
Android 4.0 (API Level 11) 之后,禁止在主线程(UI线程)上进行任何网络操作,如果在主线程发起网络请求,会抛出 NetworkOnMainThreadException 异常,这是为了防止网络请求阻塞 UI,导致应用“无响应”(ANR)。

解决方案:
- Java: 使用
AsyncTask,Thread+Handler, 或ExecutorService。 - Kotlin: 使用 协程,这是目前最推荐、最简洁的方式。
b. 网络权限
你的应用必须告诉系统它需要访问网络,在 app/src/main/AndroidManifest.xml 文件中添加以下权限:
<!-- 允许应用打开网络套接字 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 如果你的应用使用的是明文 HTTP 流量,从 Android 9 (API 28) 开始,
必须在 manifest 中配置 cleartextTrafficPermitted="true"。
强烈建议使用 HTTPS。 -->
<application
...
android:usesCleartextTraffic="true"
...>
...
</application>
c. HTTPS 与安全
现代应用必须使用 HTTPS 协议进行通信,以确保数据传输的加密和安全性,如果你使用自签名证书或开发环境的证书,需要在代码中进行信任处理(生产环境请谨慎)。
方法一:使用原生 HttpURLConnection
这是 Android SDK 自带的工具,无需额外依赖,适合简单的网络请求。
特点
- 优点: 无需依赖,轻量级,官方维护。
- 缺点: API 较为繁琐,需要手动管理线程和解析。
GET 请求示例 (Kotlin)
import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import java.io.BufferedReader
import java.io.InputStreamReader
import java.net.HttpURLConnection
import java.net.URL
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val textView: TextView = findViewById(R.id.textView)
val button: Button = findViewById(R.id.button)
button.setOnClickListener {
// 在 Kotlin 中,我们通常使用协程来处理网络请求
// 这里为了展示 HttpURLConnection,我们创建一个新的线程
Thread(Runnable {
try {
val apiUrl = "https://api.github.com/users/octocat"
val url = URL(apiUrl)
val urlConnection = url.openConnection() as HttpURLConnection
// 设置请求方法
urlConnection.requestMethod = "GET"
// 设置连接超时和读取超时
urlConnection.connectTimeout = 5000
urlConnection.readTimeout = 5000
// 检查响应码
if (urlConnection.responseCode == HttpURLConnection.HTTP_OK) {
val inputStream = urlConnection.inputStream
val reader = BufferedReader(InputStreamReader(inputStream))
val response = StringBuilder()
var line: String?
while (reader.readLine().also { line = it } != null) {
response.append(line)
}
reader.close()
inputStream.close()
// 在主线程更新 UI
runOnUiThread {
textView.text = response.toString()
}
} else {
// 在主线程更新 UI
runOnUiThread {
textView.text = "Error: ${urlConnection.responseCode}"
}
}
} catch (e: Exception) {
e.printStackTrace()
// 在主线程更新 UI
runOnUiThread {
textView.text = "Exception: ${e.message}"
}
}
}).start()
}
}
}
方法二:使用 OkHttp (强烈推荐)
OkHttp 是目前 Android 开发中最流行的网络库之一,它高效、易用,并内置了连接池、拦截器等强大功能。
添加依赖
在 app/build.gradle.kts (或 app/build.gradle) 文件中添加:
// build.gradle.kts (Kotlin DSL)
dependencies {
implementation("com.squareup.okhttp3:okhttp:4.12.0") // 使用最新版本
}
// build.gradle (Groovy DSL)
dependencies {
implementation 'com.squareup.okhttp3:okhttp:4.12.0'
}
GET 请求示例 (Kotlin + 协程)
import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.*
import okhttp3.OkHttpClient
import okhttp3.Request
import java.io.IOException
class OkHttpActivity : AppCompatActivity() {
private val client = OkHttpClient()
private val scope = MainScope() // 创建一个主作用域
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val textView: TextView = findViewById(R.id.textView)
val button: Button = findViewById(R.id.button)
button.setOnClickListener {
// 在协程作用域内发起网络请求
scope.launch {
try {
val response = get("https://api.github.com/users/octocat")
// 在主线程更新 UI
textView.text = response
} catch (e: Exception) {
textView.text = "Error: ${e.message}"
}
}
}
}
private suspend fun get(url: String): String = withContext(Dispatchers.IO) {
val request = Request.Builder()
.url(url)
.build()
client.newCall(request).execute().use { response ->
if (!response.isSuccessful) throw IOException("Unexpected code $response")
response.body!!.string()
}
}
override fun onDestroy() {
super.onDestroy()
scope.cancel() // 在 Activity 销毁时取消协程,防止内存泄漏
}
}
POST 请求示例 (发送 JSON)
// 在 OkHttpActivity 中添加这个方法
private suspend fun post(url: String, json: String): String = withContext(Dispatchers.IO) {
val mediaType = "application/json; charset=utf-8".toMediaType()
val body = json.toRequestBody(mediaType)
val request = Request.Builder()
.url(url)
.post(body)
.build()
client.newCall(request).execute().use { response ->
if (!response.isSuccessful) throw IOException("Unexpected code $response")
response.body!!.string()
}
}
// 调用示例
// val json = """{"name": "John", "role": "Developer"}"""
// val response = post("https://your-api-endpoint.com/users", json)
方法三:使用 Retrofit (高级)
Retrofit 是一个类型安全的 HTTP 客户端,它将 REST API 的端点定义为 Java/Kotlin 接口,它底层通常使用 OkHttp,并专注于将 JSON/XML 响应自动解析成你定义的数据模型(POJO/DTO)。
特点
- 优点: 代码非常简洁,类型安全,自动解析,易于维护和测试。
- 缺点: 引入了额外的依赖(Retrofit + OkHttp + 解析器),学习曲线稍高。
设置步骤
-
添加依赖
// build.gradle.kts dependencies { implementation("com.squareup.retrofit2:retrofit:2.9.0") implementation("com.squareup.retrofit2:converter-gson:2.9.0") // Gson 解析器 implementation("com.squareup.okhttp3:logging-interceptor:4.12.0") // 日志拦截器 (可选) } -
定义数据模型
// User.kt data class User( val login: String, val id: Int, val avatar_url: String, val name: String? ) -
创建 API 接口
// ApiService.kt import retrofit2.http.GET import retrofit2.http.Path interface ApiService { @GET("users/{username}") suspend fun getUser(@Path("username") username: String): User } -
创建 Retrofit 实例并进行网络请求
import android.os.Bundle import android.widget.Button import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory import kotlinx.coroutines.* class RetrofitActivity : AppCompatActivity() { private lateinit var apiService: ApiService private val scope = MainScope() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val textView: TextView = findViewById(R.id.textView) val button: Button = findViewById(R.id.button) // 1. 创建 Retrofit 实例 val retrofit = Retrofit.Builder() .baseUrl("https://api.github.com/") .addConverterFactory(GsonConverterFactory.create()) .build() // 2. 创建 API 接口的实现 apiService = retrofit.create(ApiService::class.java) button.setOnClickListener { scope.launch { try { // 3. 调用接口方法,发起网络请求 val user = apiService.getUser("octocat") // 在主线程更新 UI textView.text = "Name: ${user.name}\nLogin: ${user.login}" } catch (e: Exception) { textView.text = "Error: ${e.message}" } } } } override fun onDestroy() { super.onDestroy() scope.cancel() } }
后台执行网络请求
使用 Coroutine (Kotlin)
这是目前 Android 官方推荐的并发处理方式,它非常轻量,可以简化异步代码,使其看起来像同步代码。
Dispatchers.Main: 主线程,用于更新 UI。Dispatchers.IO: 专门用于执行磁盘或网络等 I/O 操作的线程池。withContext(Dispatchers.IO) { ... }: 将代码块中的任务切换到 IO 线程执行,并等待结果返回。
在上面的 OkHttp 和 Retrofit 示例中,我们已经展示了如何使用协程。
解析服务器响应
手动解析
对于简单的 JSON,可以使用 JSONObject 和 JSONArray 来手动解析,但非常繁琐且容易出错。
// 不推荐,仅作了解
try {
JSONObject jsonObject = new JSONObject(responseString);
String name = jsonObject.getString("name");
int id = jsonObject.getInt("id");
// ...
} catch (JSONException e) {
e.printStackTrace();
}
使用 Gson / Moshi 自动解析
这是推荐的方式,你只需要创建一个与 JSON 结构匹配的数据类(Kotlin)或 POJO(Java),然后库会自动将 JSON 字符串转换成对象。
使用 Gson (配合 Retrofit 或 OkHttp)
- 添加依赖 (前面已添加)
- 定义数据类 (前面已定义
User.kt) - 转换
- Retrofit: 自动完成,只需在
Retrofit.Builder中添加addConverterFactory(GsonConverterFactory.create())。 - OkHttp: 手动调用
val gson = Gson() val user = gson.fromJson(responseBody, User::class.java)
- Retrofit: 自动完成,只需在
最佳实践与总结
| 特性 | HttpURLConnection |
OkHttp |
Retrofit |
|---|---|---|---|
| 易用性 | 低 | 中 | 高 |
| 功能 | 基础 | 强大 (拦截器, 缓存, WebSocket) | 极强 (基于接口, 类型安全) |
| 性能 | 一般 | 优秀 (连接池) | 优秀 (底层 OkHttp) |
| 依赖 | 无 | 1 个 (OkHttp) | 2-3 个 (Retrofit, OkHttp, 解析器) |
| 适用场景 | 简单 demo, 不想引入第三方库 | 大多数网络请求, 特别是需要高级功能时 | 复杂 API, 大型项目, 追求代码整洁和类型安全 |
最终建议
- 对于初学者或简单项目: 可以从
HttpURLConnection开始,了解基本原理,但实际项目中,强烈建议直接学习OkHttp。 - 对于绝大多数 Android 项目:
OkHttp+Kotlin 协程是黄金组合,它提供了强大的功能和简洁的异步代码。 - 对于企业级应用或复杂 API:
Retrofit+OkHttp+Kotlin 协程是行业标准,它能极大地提升代码的可读性、可维护性和健壮性。
其他重要考虑
- 错误处理: 总是检查 HTTP 状态码 (如 200, 404, 500) 和网络异常(如
SocketTimeoutException,UnknownHostException)。 - 数据解析: 对于复杂的 JSON,
Moshi通常比Gson性能更好,并且与 Kotlin 的集成更无缝。 - 安全性: 始终使用 HTTPS,并妥善处理证书。
- 日志: 使用
HttpLoggingInterceptor(OkHttp) 来调试你的网络请求和响应,非常方便。
