惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Attack and Defense Labs
Attack and Defense Labs
宝玉的分享
宝玉的分享
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
D
Darknet – Hacking Tools, Hacker News & Cyber Security
V
Vulnerabilities – Threatpost
博客园_首页
Engineering at Meta
Engineering at Meta
F
Fortinet All Blogs
C
Cyber Attacks, Cyber Crime and Cyber Security
罗磊的独立博客
V
Visual Studio Blog
Know Your Adversary
Know Your Adversary
Hacker News - Newest:
Hacker News - Newest: "LLM"
美团技术团队
L
LINUX DO - 最新话题
The Last Watchdog
The Last Watchdog
博客园 - 三生石上(FineUI控件)
T
Tor Project blog
云风的 BLOG
云风的 BLOG
N
Netflix TechBlog - Medium
MyScale Blog
MyScale Blog
The GitHub Blog
The GitHub Blog
有赞技术团队
有赞技术团队
I
InfoQ
Last Week in AI
Last Week in AI
V2EX - 技术
V2EX - 技术
量子位
S
Secure Thoughts
L
LangChain Blog
The Hacker News
The Hacker News
H
Help Net Security
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
小众软件
小众软件
K
Kaspersky official blog
Security Archives - TechRepublic
Security Archives - TechRepublic
Google Online Security Blog
Google Online Security Blog
I
Intezer
Vercel News
Vercel News
Hacker News: Ask HN
Hacker News: Ask HN
Cisco Talos Blog
Cisco Talos Blog
Google DeepMind News
Google DeepMind News
S
Securelist
阮一峰的网络日志
阮一峰的网络日志
G
Google Developers Blog
Help Net Security
Help Net Security
Martin Fowler
Martin Fowler
爱范儿
爱范儿
Y
Y Combinator Blog
C
Check Point Blog

阿尔的代码屋 | 全栈技术笔记

在 Android Termux 环境下安装 Hermes Agent 的踩坑与完美解决实践 开发日志| 阿尔的代码屋 VS Code 连接 WSL 精确每 10 分钟掉线 排坑笔记 | 阿尔的代码屋 [object Object] typing_extensions 有用(四):使用 TypeIs 替代危险的 cast,做最严谨的类型收窄 | 阿尔的代码屋 GoRouter 结合 Isar 运行 Widget 测试并发/粘性线程死锁卡死排坑笔记 | 阿尔的代码屋 typing_extensions 有用(三):使用 Unpack 结合 TypedDict 给 **kwargs 装上透视眼 | 阿尔的代码屋 typing_extensions 有用(二):使用 @override 打造重构代码时的“防呆神器” | 阿尔的代码屋 Flutter 并发测试踩坑实录 - IsarCore 动态库下载冲突与 Widget 测试 HTTP 拦截全链路解决 | 阿尔的代码屋 typing_extensions 有用(一):使用 Self 终结继承时的类型推断灾难 | 阿尔的代码屋 基于 Cloudflare Pages 的纯前端 WebAssembly 应用自动化部署实践 | 开发日志 | 阿尔的代码屋 基于 VS Code 远程开发的 GPU Docker 容器自动清理方案实践 开发日志| 阿尔的代码屋 Patrol iOS 集成测试排坑实录 - xcodebuild exit code 70 全链路解决 | 阿尔的代码屋 Flutter E2E 测试从 integration_test 迁移到 Patrol - 实践笔记 | 阿尔的代码屋 Linux/macOS 下 micromamba 报错 Shard Index not available 与极度卡顿 排坑笔记 | 阿尔的代码屋 critical libmamba Shell not initialized micromamba报错 subprocess 无法修改父 Shell - 排坑笔记 | 阿尔的代码屋 VS Code Remote-SSH: 彻底告别重复输入密码 - 排坑笔记 | 阿尔的代码屋 Git 报警: inexact rename detection was skipped - 排坑笔记 | 阿尔的代码屋 解决群晖 NAS SSL 证书自动部署难题 | 阿尔的代码屋 Windows 下 Git error: fatal: refusing to work with credential missing host field - 排坑笔记 | 阿尔的代码屋 VS Code 调试 Python 第三方库源码的配置 - 开发技巧| 阿尔的代码屋 VS Code Remote Tunnels本地连接调试Kaggle GPU - 开发技巧| 阿尔的代码屋 Windows下Git error: open(xxxx) Filename too long - 排坑笔记 | 阿尔的代码屋 记录2026年零预约港卡开户实录避坑 告别孤岛:拥抱 MCP 协议,为大模型打造标准“USB 接口” - 大模型实战 08 完结篇 | 阿尔的代码屋 从 ReAct 到 Workflow:基于云端 API 构建事件驱动的智能体 - 大模型实战 07 额外篇 | 阿尔的代码屋 基于 LlamaIndex ReAct 框架手搓全自动博客监控 Agent - 大模型实战 07 | 阿尔的代码屋 在 Kaggle 上用 Unsloth 极速微调 Qwen3 - 大模型实战 06 | 阿尔的代码屋 大模型微调实战详解 - 大模型实战 05 | 阿尔的代码屋 基于 ChromaDB 打造工程级 RAG 系统 - 大模型实战 04 | 阿尔的代码屋 拆解 Transformers 原理与图解 - 大模型实战 03 | 阿尔的代码屋 云端炼丹房 2:Kaggle 上手指南 - 大模型实战 03预备 | 阿尔的代码屋 云端炼丹房:Google Colab 免费 GPU 上手指南 - 大模型实战 03预备 | 阿尔的代码屋 Open WebUI 部署与 RAG 实战 - 大模型实战 02 | 阿尔的代码屋
Android 模拟器代理联网与 No Internet WiFi 锁死排坑笔记 | 阿尔的代码屋
Algieba · 2026-07-06 · via 阿尔的代码屋 | 全栈技术笔记

核心摘要 (TL;DR)

  • 问题现象:模拟器配置了宿主机代理后依然无法访问 google.com;WiFi 一直提示 “No Internet” 或带有感叹号,且在开启 WiFi 代理时连国内的百度、必应等网页也全面超时挂起(ERR_TIMED_OUT)。
  • 根本原因
    1. 代理双重冲突 (Chaining Conflict):同时使用了命令行启动参数 -http-proxy 以及模拟器内置 WiFi 的 Manual Proxy 设置,两个代理层级相互嵌套拦截,造成网络死循环。
    2. Captive Portal 锁死路由:Android 系统在连接 WiFi 时会尝试测试 Google 检测服务器以评估网络状况。检测失败后判定为 “No internet”,系统会自动选择切断该 WiFi 的实际出口路由或强制回退到蜂窝数据,导致代理配置直接失效。
    3. Clash 局域网限制:未开启 Clash 的 “允许局域网 (Allow LAN)” 开关。此时 Clash 仅监听 127.0.0.1,而模拟器发往网关 10.0.2.2 的入站连接被宿主机直接拒绝。
    4. 系统镜像型号不对:使用了 google_apis 镜像,其内部完全缺失 Google Play 商店客户端,导致无法正常连接 Play 商店。
  • 关键解法
    1. 关闭连网检测:通过 ADB 命令 captive_portal_mode 0 彻底关闭 Android 系统的网络连通性检查。
    2. 规避代理冲突:不要同时设置命令行代理与内置 WiFi 代理;在宿主机 Clash 中开启 “允许局域网” 后,使用独立 WiFi 手动代理(10.0.2.2:7890)。
    3. 使用 Play 镜像:确保 AVD 设备使用 google_play 系统镜像而非 google_apis 镜像。

问题概览卡片

基本信息

  • 问题分类:模拟器网络联通 / 代理配置冲突 / 开发服务接入调试
  • 环境说明:macOS (M系列) / Android SDK Emulator / Clash Verge / Android 14+
  • 触发条件:在未开全局 Tun 模式下,多处重叠配置代理,或由于国内网络环境下模拟器对 Google 检测服务不通引发的自动降级。
  • 报错表现
    1
    2
    3
    This site can't be reached
    www.google.com took too long to respond.
    ERR_TIMED_OUT
    并且模拟器 WiFi 标志上出现小感叹号,提示 “No internet”。

1. 现象描述与现场还原

在日常开发或接入需要连接 Google 服务的 App 时,我们需要在模拟器上连接 Google 服务以测试各项网络接口或登录商店。

当我们尝试将模拟器的流量导入宿主机(Mac)运行的代理客户端(如 Clash 端口 7890)时,经常会遇到以下现象:

  • 模拟器内开浏览器访问谷歌,提示 ERR_TIMED_OUT
  • 模拟器 WiFi (AndroidWifi) 状态一直显示为 “Connected, no internet” (已连接,无互联网),并且带有一个感叹号。
  • 最诡异的是:如果关闭 WiFi 改用蜂窝流量 (Mobile Data),能正常访问百度、必应等国内网站;但只要连着配置了代理的 WiFi,连百度也一并报 ERR_TIMED_OUT,网络完全瘫痪。

2. 根本原因分析

该问题背后有三个互相层叠的隐藏网络机制:

2.1 模拟器网络沙箱与 10.0.2.2 宿主映射

Android 模拟器运行在独占的虚拟机沙箱中,它的网络是一个虚拟的局域网网段。

  • 在模拟器内部,10.0.2.2 是指向宿主机 Mac 环回接口(Loopback / 127.0.0.1)的特殊网关。
  • 局域网入站拦截:如果您的 Clash 客户端未开启 “允许局域网 (Allow LAN)”,Clash 核心将只监听 127.0.0.1,任何来自虚拟网桥(来自 10.0.2.16 等模拟器 IP 发往 10.0.2.2)的连接都会被 Clash 视作 LAN 入站流量并直接拒绝接收。

2.2 Captive Portal 锁死路由 (No Internet 机制)

当 Android 连上 WiFi 后,会向 Google 专属服务器发送一个轻量 HTTP 请求(connectivitycheck.gstatic.com)以确定是否需要弹窗输入网页认证。

  • 如果在代理生效前,该检测请求被墙或超时,Android 会认定此 WiFi “没有互联网连接”。
  • 网络降级逻辑:为了保证手机能正常通网,Android 系统在判定 WiFi 无网时,会自动忽略此 WiFi 的路由出口,强行把全局流量降级退回到不含代理配置的蜂窝移动网络(Cellular Data)。
  • 这就导致了“连着 WiFi 无网,断开 WiFi 能用蜂窝网络上国内网,但代理和谷歌永远不通”的恶性循环。

2.3 命令行 -http-proxy 与 WiFi 手动代理的双重冲突

有些开发者为了省事,使用如下命令行参数启动模拟器:

1
emulator -avd Pixel_9_Pro -http-proxy http://127.0.0.1:7890

启动后,又去模拟器的系统设置(WiFi Advanced Settings)里手动设置了 10.0.2.2:7890 的 Manual Proxy。

  • 此时,命令行参数在模拟器底层进程(QEMU 级别)劫持流量;而系统 WiFi 设置在 Android 系统级别又强行做了一层代理包装。
  • 这种代理叠加导致了 Proxy Chaining 环路冲突,两层代理相互等待,导致所有 HTTP 请求死锁,直接报 ERR_TIMED_OUT

3. 解决方案与最佳实践

3.1 一键消除 No Internet:关闭系统 Captive Portal 检测

在 Mac 宿主机上,我们直接使用 Android SDK 附带的 adb 工具对运行中的模拟器下发全局配置,彻底关掉 Google 连网检测,使 WiFi 永久保持在“有网”的健康路由状态。

请在终端中执行以下命令(模拟器需保持运行状态):

1
2
3
4
5
6
7

~/Library/Android/sdk/platform-tools/adb shell settings put global captive_portal_mode 0
~/Library/Android/sdk/platform-tools/adb shell settings put global captive_portal_detection_enabled 0


~/Library/Android/sdk/platform-tools/adb shell svc wifi disable
~/Library/Android/sdk/platform-tools/adb shell svc wifi enable

执行后,模拟器的 WiFi 图标感叹号会瞬间消失,路由状态恢复正常。


3.2 代理联网配置方案(三选一)

在关闭检测后,建议选择以下其中一种方式干净地配置代理,切勿重叠使用:

方案 A:宿主开启局域网共享 + 模拟器 WiFi 手动代理(最常用)

  1. 宿主配置:在 Mac 的 Clash 菜单中,勾选 “允许局域网连接” (Allow LAN) 开关。
  2. 模拟器配置
    • 启动模拟器时不要-http-proxy 参数。
    • 进入模拟器 WiFi (AndroidWifi) -> 铅笔编辑 -> 展开高级选项 -> Proxy 选择 Manual
    • Host name 填入宿主网关:10.0.2.2
    • Port 填入 Clash 的 HTTP 端口:7890
    • 保存。

方案 B:宿主开启 Tun 模式 + 模拟器无代理参数(最省心 🌟)

  1. 安装核心服务:在 Mac 的 Clash 中点击“更多设置” -> 找到 “服务模式” (Service Mode) 点击安装并授权(授权后其状态图标会变为绿色)。
  2. 开启 Tun:在 Clash 主菜单中勾选开启 “Tun 模式”(此时 Mac 会建立一块接管整机流量的虚拟网卡)。
  3. 模拟器配置
    • 将模拟器内所有的 WiFi 代理修改为 None (无)
    • 直接运行最普通的模拟器启动命令,即可完美接入代理网络,无需配置任何代理参数。

方案 C:仅使用命令行参数代理(免改系统设置)

  1. 模拟器配置:将模拟器内的 WiFi 代理重置为 None (无)
  2. 启动命令:若 HTTP 代理不通,推荐采用兼容性更佳的 SOCKS5 协议从命令行启动:
    1
    ~/Library/Android/sdk/emulator/emulator -avd Pixel_9_Pro -http-proxy socks5://127.0.0.1:7891 &
    (注:7891 为 Clash 的默认 SOCKS5 端口)

4. 补充说明:Google Play 商店镜像注意事项

在解决网络问题后,若要测试真正的 Google Play 商店或相关谷歌服务,还需要确保您的 Android 模拟器不是 google_apis 镜像。

  • 如何判断:启动模拟器时的命令行日志如果输出如下内容,则说明是 google_apis 镜像:
    Found systemPath .../google_apis/arm64-v8a/
  • 正确做法:在 Android Studio 的 Device Manager 中创建虚拟设备时,必须选择带“三角 Play 商店图标”的物理机型,并下载 Target 标明为 Android ... (Google Play) 的系统镜像(此时镜像存储路径应为 .../google_play/arm64-v8a/)。
  • 登录 Google Play 商店后,配合上述代理机制,即可在本地开发环境中轻松访问商店并下载调试应用。

5. 关于配置持久性与 Wipe Data 的说明

很多开发者会担心这些配置是否每次启动模拟器或重启电脑后都需要重新设置。答案是:不需要,这些设置是持久生效的

  • ADB 修改全局设置:我们执行的 captive_portal 禁用命令写入的是 Android 虚拟机的系统全局数据库(保存在 /data 分区内)。模拟器重启或关机并不会丢失这一配置。
  • WiFi 代理配置:系统内置的 WiFi 代理设置也会被保存在模拟器的本地网络配置中,同样永久生效。
  • Clash 局域网设置:宿主机的 Clash “允许局域网连接”设置属于本地应用配置,软件重启依然保持开启。

⚠️ 例外情况
唯一会导致上述配置失效的操作是,在 Android Studio Device Manager 中对该模拟器执行了 “Wipe Data” (擦除数据/恢复出厂设置)。擦除数据会清空整个 /data 分区,届时您需要重新下发一次 ADB 连网检测禁用命令并重置 WiFi 手动代理。