在 Android 开发及现代网络编程中,HTTP 访问网络是应用与服务器进行数据交互的核心机制,随着 Android 10(API 29)及更高版本的普及,网络通信的安全性和规范性要求显著提高,传统的 HttpURLConnection 虽仍可用,但 Google 官方更推荐使用 HttpURLConnection 的改进版或第三方库如 OkHttp、Retrofit,以下将详细解析 HTTP 访问网络的关键步骤、权限配置、最佳实践及常见问题。

网络权限配置
在 Android 系统中,访问网络属于敏感操作,必须在 AndroidManifest.xml 文件中声明相应的权限。
| 权限名称 | 用途说明 | 是否必需 |
|---|---|---|
INTERNET |
允许应用程序打开网络套接字,访问互联网。 | 是 |
ACCESS_NETWORK_STATE |
允许应用程序访问网络状态信息(如判断是否有网)。 | 推荐 |
ACCESS_WIFI_STATE |
允许应用程序访问 Wi-Fi 状态。 | 可选 |
配置示例:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
明文流量限制(Cleartext Traffic)
从 Android 9(API 28)开始,默认禁止明文 HTTP 流量,强制要求使用 HTTPS,如果应用仍需使用 HTTP,需在 AndroidManifest.xml 的 <application> 标签中显式允许。
<application
android:usesCleartextTraffic="true"
... >
<!-其他配置 -->
</application>
注意:在生产环境中,强烈建议全面迁移至 HTTPS,以保障数据传输安全。
核心实现方式
使用 HttpURLConnection(原生方式)
HttpURLConnection 是 Java 标准库的一部分,无需额外依赖,但由于其 API 较为底层,需要手动处理连接、输入输出流及异常。
关键步骤:
- 创建 URL 对象。
- 打开连接并设置请求方法(GET/POST)。
- 设置请求头(Headers)。
- 发送请求并获取响应码。
- 读取响应数据。
- 务必关闭流和连接。
代码片段示例:
new Thread(new Runnable() {
@Override
public void run() {
HttpURLConnection connection = null;
try {
URL url = new URL("https://api.example.com/data");
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(10000);
connection.setReadTimeout(10000);
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
InputStream inputStream = connection.getInputStream();
// 解析 inputStream...
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
}
}
}).start();
使用 OkHttp(推荐方式)
OkHttp 是一个高效、支持 HTTP/2 的 HTTP 客户端,由 Square 公司开源,它自动处理连接池、GZIP 压缩和缓存,API 更加简洁。

优势:
- 支持同步和异步请求。
- 自动处理重定向。
- 连接复用,减少延迟。
代码片段示例:
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://api.example.com/data")
.get()
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
String responseData = response.body().string();
// 在主线程更新 UI
}
}
});
网络请求的最佳实践
-
避免在主线程执行网络请求
网络请求是耗时操作,必须在子线程中执行,Android 4.0 之后,直接在主线程进行网络请求会抛出NetworkOnMainThreadException,推荐使用AsyncTask(已废弃)、ExecutorService、Coroutine(Kotlin 协程)或RxJava。 -
设置超时时间
必须设置连接超时(Connect Timeout)和读取超时(Read Timeout),防止因网络不稳定导致应用长时间无响应。 -
处理异常
网络环境复杂,需捕获IOException、SocketTimeoutException等异常,并向用户反馈友好的错误提示。 -
数据缓存策略
对于不常变化的数据,可利用 OkHttp 的缓存机制或手动实现内存/磁盘缓存,提升加载速度并节省流量。 -
使用 Retrofit 简化开发
Retrofit 是基于 OkHttp 的 REST 客户端,通过注解将 HTTP API 映射为 Java/Kotlin 接口,极大简化了网络请求代码,是 Android 开发的事实标准。
常见问题排查
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
Cleartext HTTP traffic not permitted |
Android 9+ 默认禁止明文流量 | 在 Manifest 中设置 usesCleartextTraffic="true" 或改用 HTTPS |
NetworkOnMainThreadException |
在主线程执行网络请求 | 将网络请求移至子线程或使用异步框架 |
| 请求超时 | 服务器响应慢或网络差 | 增加超时时间,检查服务器状态,优化请求逻辑 |
| 403 Forbidden | 缺少必要的请求头(如 User-Agent) | 检查服务器要求,添加缺失的请求头 |
相关问题与解答
问题 1:为什么 Android 9 及以上版本默认禁止明文 HTTP 流量?如何在不修改代码逻辑的情况下临时允许 HTTP 请求用于调试?

解答:
Android 9 引入明文流量限制的主要原因是出于安全考虑,HTTP 协议以明文形式传输数据,容易被中间人攻击(MITM)窃取敏感信息(如用户名、密码、支付信息等),强制使用 HTTPS 可以确保数据的加密传输和完整性。
在开发调试阶段,如果后端服务尚未支持 HTTPS,可以通过在 AndroidManifest.xml 的 <application> 标签中添加 android:usesCleartextTraffic="true" 来临时允许明文流量,还可以创建 network_security_config.xml 文件,通过 <domain> 标签精确指定允许明文流量的域名,从而实现更细粒度的控制,避免全局开启带来的安全风险。
问题 2:在 Android 开发中,Retrofit 和 OkHttp 之间是什么关系?为什么推荐使用 Retrofit 而不是直接使用 OkHttp?
解答:
Retrofit 和 OkHttp 是互补关系,而非竞争关系,OkHttp 是一个底层的 HTTP 客户端库,负责处理连接管理、协议细节、缓存等底层工作,而 Retrofit 是一个类型安全的 HTTP 客户端,它构建在 OkHttp 之上(默认使用 OkHttp 作为执行引擎)。
推荐使用 Retrofit 的原因包括:
- API 设计简洁:通过注解(如
@GET,@POST,@Body)将 HTTP 请求映射为 Java/Kotlin 接口,代码更具可读性和维护性。 - 自动序列化/反序列化:Retrofit 支持集成 Gson、Moshi 等转换器,自动将 JSON 响应转换为对象,或将对象转换为 JSON 请求体,减少了手动解析代码的编写。
- 异步支持:Retrofit 原生支持异步请求,简化了线程切换和回调处理。
- 扩展性强:可以轻松添加拦截器(Interceptor)用于日志记录、统一添加 Token 等,底层依然由 OkHttp 提供强大的性能支持。
简而言之,OkHttp 负责“怎么做”(底层执行),Retrofit 负责“做什么”(高层接口定义),两者结合使用能实现高效且优雅的网络请求开发。
原创文章,发布者:酷盾叔,转转请注明出处:https://www.kd.cn/ask/498593.html