如何解决 Android Studio 模拟器的网络连接问题?
访问电脑上的本地 API 时,先把应用中的 localhost 或 127.0.0.1 改为 10.0.2.2,再检查端口、网络权限和 HTTP 安全配置。在 Android Studio 自带的 Android Emulator 中,10.0.2.2 用于访问宿主机的回环接口,localhost 则指向模拟器自身。Android 官方说明
如果模拟器浏览器连外网也打不开,再排查 DNS、代理、VPN 和模拟器状态。“连接失败”本身不足以判断原因,需要先确定问题出在哪一段。
1. 先区分外网故障和本地 API 故障
- 在电脑上访问一个正常的外网网站,确认宿主机网络可用。
- 在模拟器浏览器中访问同一个网站。
- 在电脑上请求本地 API。
- 在模拟器浏览器中访问对应的本地 API 地址。
假设后端运行在电脑的 8080 端口,且有 /health 接口,可以在电脑终端执行:
curl -v http://127.0.0.1:8080/health
再在模拟器浏览器中打开:
http://10.0.2.2:8080/health
端口和路径要换成项目实际使用的值。浏览器地址栏适合测试 GET 接口;对于需要 POST 或鉴权的接口,还要核对请求方法、请求体和请求头。
| 检查结果 | 优先排查 |
|---|---|
| 电脑也无法访问本地 API | 后端是否启动、端口和路径是否正确 |
| 模拟器能访问外网,无法访问本地 API | API 地址、后端监听地址、端口映射、防火墙 |
| 模拟器浏览器能访问 API,应用失败 | 应用权限、HTTP 限制、证书、请求配置 |
| 电脑能上网,模拟器无法访问外网 | 模拟器代理、VPN、DNS、网络状态 |
浏览器能访问 API,说明该浏览器的请求可以到达服务。应用有自己的权限和安全配置,仍需单独检查。
2. 修正本地 API 地址,确认后端端口可达
如果电脑上的后端地址是:
http://localhost:8080/api/
应用在 Android Emulator 中运行时,可以改为:
val baseUrl = "http://10.0.2.2:8080/api/"
8080 必须是宿主机实际提供服务的端口。同时确认请求使用 HTTP 还是 HTTPS,以及路径中的 API 前缀是否正确。
后端监听宿主机的 127.0.0.1 时,可以通过 10.0.2.2 访问,无须一律改成 0.0.0.0。如果后端运行在 Docker、WSL 或其他虚拟机中,先将服务暴露到宿主机可访问的端口,再通过这个端口连接。
也可以用 adb reverse 建立反向端口转发:
adb devices
adb reverse tcp:8080 tcp:8080
adb reverse --list
建立转发后,应用可以使用:
http://127.0.0.1:8080/api/
第一个端口属于设备端,第二个端口属于宿主机端。这种方法也适用于通过 ADB 连接的真机。反向端口转发说明
连接多个设备时,用 adb -s SERIAL reverse ... 指定目标,将 SERIAL 替换为 adb devices 显示的序列号。设备重连后,要检查转发是否还在。不再需要时可以删除:
adb reverse --remove tcp:8080
10.0.2.2 是 Android Emulator 的特殊地址,不能直接用于普通真机。
3. 检查网络权限和 HTTP 安全配置
声明网络权限
在 app/src/main/AndroidManifest.xml 的 <manifest> 内、<application> 外声明:
<uses-permission android:name="android.permission.INTERNET" />
如果应用还需要读取网络状态,再声明:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
这两个权限都不需要在运行时弹窗申请。修改 Manifest 后,重新构建并安装应用。网络权限说明
只为本地调试放行 HTTP
如果 Logcat 出现以下错误,说明请求受到明文 HTTP 策略限制:
CLEARTEXT communication to 10.0.2.2 not permitted by network security policy
对于以 Android 9(API 28)及以上为目标的应用,默认网络安全配置会限制明文流量。Network Security Configuration 文档
如果项目尚未配置 android:networkSecurityConfig,可以在调试构建中加入以下配置。
创建 app/src/debug/AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:networkSecurityConfig="@xml/network_security_config_debug" />
</manifest>
创建 app/src/debug/res/xml/network_security_config_debug.xml:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain>10.0.2.2</domain>
<domain>localhost</domain>
<domain>127.0.0.1</domain>
</domain-config>
</network-security-config>
这些例外只放在 src/debug 中,用于本地联调。如果项目已有 Network Security Configuration,应结合现有配置和构建变体进行调整,并检查合并后的 Manifest,避免直接覆盖已有规则。
使用 HTTPS 时,如果出现 SSLHandshakeException,应检查证书信任链、有效期,以及证书是否匹配请求中的主机名或 IP。放行 HTTP 无法修复 HTTPS 证书问题,也不要用信任所有证书或关闭主机名校验的方式处理。
4. 模拟器无法上网时,再检查 DNS、代理和启动状态
先确认模拟器已关闭飞行模式、启用网络,再按以下顺序排查:
- 检查模拟器的代理配置。电脑代理服务停止或端口改变后,旧配置可能仍会影响请求。
- 检查宿主机的 VPN、代理和防火墙规则。必要时,在网络策略允许的情况下切换网络,对比结果。
- 完全关闭模拟器,在 Device Manager 中使用
Cold Boot冷启动。菜单名称可能随 Android Studio 版本变化。 - 如果报错明确指向域名解析,再尝试指定 DNS。
例如,先关闭对应的 AVD,再从命令行启动:
emulator -list-avds
emulator -avd YOUR_AVD_NAME -dns-server 8.8.8.8
将 YOUR_AVD_NAME 替换为实际 AVD 名称。emulator 位于 Android SDK 的 emulator 目录;终端找不到命令时,可以使用完整路径。
8.8.8.8 只是示例,应选择当前网络允许且能够访问的 DNS。公司内部域名可能无法通过公共 DNS 解析,需要使用公司提供的 DNS。模拟器 DNS 故障排查
直接访问 10.0.2.2 不涉及域名解析,因此修改 DNS 通常无法解决这个地址的连接拒绝问题。
如果仍然失败,可以更新 Android Emulator,再新建一个 AVD 进行对比。Wipe Data 会清除该 AVD 内的应用和数据,留到后面再考虑。
5. 根据日志决定下一步
在 Android Studio 的 Logcat 中查看完整异常,同时检查后端访问日志,别只保留界面上的“网络错误”提示。
| 日志或现象 | 含义及处理方向 |
|---|---|
UnknownHostException | 检查域名拼写、DNS 和代理 |
Connection refused / ECONNREFUSED | 检查服务是否监听该地址与端口,以及转发是否建立 |
| 连接超时 | 检查路由、防火墙、代理和服务响应情况 |
CLEARTEXT ... not permitted | 调整调试构建的明文流量配置 |
SSLHandshakeException | 根据内部异常检查证书和 TLS 配置 |
HTTP 401、403、404 或 5xx | 已收到 HTTP 响应,应检查鉴权、路径、服务端或中间代理 |
每次只改一个配置,然后重新发送同一个请求。记录实际请求 URL、完整异常、HTTP 状态码,以及后端是否收到请求,逐步缩小排查范围。
备注:内容仅供参考。
