简介:这份文档面向Android开发初学者与需要联调测试的工程师,聚焦模拟器与电脑不在同一网段、无法联网或通信失败这一常见痛点,系统梳理AVD模拟器IP与DNS的修改流程。内容涵盖启动模拟器、通过adb shell进入命令行、用getprop读取默认DNS(10.0.2.3)与IP(10.0.2.15)、以setprop改写DNS和IP到电脑同网段,以及再次getprop验证生效,并附有device not found、device offline等报错的排查思路。资源包共1个doc文件,约47KB,篇幅精炼、步骤配图,适合作为手边速查手册。目前已有2149人学习,读者可据此快速完成模拟器网络配置,减少环境调试耗时,把精力放回功能开发与测试本身。
1. 从一次“模拟器断网”说起:avd 模拟器 IP 设置到底卡在哪
刚接手一个 Android 调试环境时,最容易翻车的不是代码,而是模拟器明明启动了、界面也亮着,可浏览器打不开网页、本地服务连不上、日志里全是超时。很多人第一反应是重装模拟器,其实问题往往出在 avd 模拟器的网络栈上:它默认跑在 10.0.2.x 这个隔离网段里,和宿主机不在同一网段,DNS 也指向 10.0.2.3。这篇安装笔记就把 Android 模拟器 IP 设置这套操作从头到尾走一遍,包括 adb 环境准备、getprop 看属性、setprop 改 DNS 和 IP、以及改完怎么验证。适合刚配 Android 开发环境的新手,也适合被模拟器网络折腾过的熟手对照版本差异。
2. 装前把环境列清:adb、platform-tools 与模拟器版本怎么选
2.1 先确认三件套:SDK、platform-tools、avd
这套操作不依赖某个特定 IDE,核心只有三样东西:Android SDK、platform-tools 目录里的 adb 可执行文件、以及一个已经创建好的 avd 模拟器。很多人把 Android Studio 装完就以为 adb 一定可用,实际上 platform-tools 是独立组件,路径通常在 SDK 根目录下。我一般先确认目录结构,再决定要不要单独补装。
常见做法是打开 SDK 安装目录,确认存在platform-tools文件夹,里面能看到adb.exe(Windows)或adb(macOS/Linux)。如果只有emulator目录没有platform-tools,说明 SDK 组件没装全,需要在 SDK Manager 里勾选 Platform-Tools 再下载。版本上不必追最新,platform-tools 保持和 SDK 同批安装即可,跨大版本混用容易出现 adb 与模拟器协议不匹配。
| 组件 | 作用 | 检查方式 |
|---|---|---|
| Android SDK | 提供模拟器与工具链根目录 | 确认 SDK 根路径存在 |
| platform-tools | 存放 adb 等命令行工具 | 目录内能看到 adb 可执行文件 |
| avd 模拟器 | 被调试的目标设备 | 设备管理器里能看到已创建的 avd |
| 系统镜像 | 模拟器运行的操作系统 | avd 详情里能看到对应 API 级别 |
这张表建议在动手前过一遍,缺哪一项先补哪一项,别等 adb shell 报错再回头找。
2.2 版本差异:不同 API 级别下网络属性的表现
原文给出的默认值是 DNS 10.0.2.3、IP 10.0.2.15,这是经典 avd 网络模型的固定分配。需要提醒的是,较新的系统镜像对net.gprs.local-ip这类属性的响应并不完全一致,有的镜像里该属性只影响部分网络接口,改完getprop能看到值变了,但实际路由未必跟着走。所以版本选择上,如果你只是做本地联调、需要模拟器和宿主机同网段通信,优先用与项目 targetSdk 接近的镜像,别为了追新用最新 API 去跑老项目。
我一般会先跑一次getprop把当前值记下来,再决定改哪些键。这样即使改坏了,也能按原值回退。原文只提了net.dns1和net.gprs.local-ip两个键,实际排查时还会看到net.dns2、dhcp.*等一堆属性,别被吓到,先盯住这两个核心键即可。
2.3 启动模拟器与进入 adb shell 的完整命令
环境确认完,第一步是把模拟器启动起来,并且让 adb 能识别到它。下面这段是 Windows 下 cmd 的操作序列,macOS/Linux 把路径分隔符换掉即可。
# 进入 SDK 下的 platform-tools 目录,路径按自己机器替换 cd C:\Android\Sdk\platform-tools # 确认 adb 能列出当前连接的设备 adb devices # 进入模拟器的 shell,后续 getprop/setprop 都在这个会话里执行 adb shelladb devices这一步很关键,正常应看到一行emulator-5554 device。如果显示offline,说明模拟器还没完全启动,等系统桌面出来再试;如果列表为空,说明 adb 没连上模拟器,先别急着改 IP,先把连接修好。adb shell进入后提示符会变成类似generic_x86:/ $,此时执行的命令都作用在模拟器内部,不是宿主机。
提示:路径里有空格时记得加引号,否则 cd 会只切到前半段,后面所有命令都会在错误目录下执行。
3. 改 IP 和 DNS:getprop 看值、setprop 落值的完整操作
3.1 用 getprop 读出默认 DNS 与 IP
进入 adb shell 后,先别急着 setprop,第一步是读。getprop不带参数会打印全部系统属性,输出很长,直接翻屏找容易漏。更稳的做法是配合过滤,只盯网络相关键。
# 打印全部属性,输出较多,适合第一次摸底 getprop # 只过滤 dns 相关属性,确认当前 DNS 指向 getprop | grep dns # 只过滤与 ip 相关的属性,确认当前地址分配 getprop | grep ipgetprop是只读操作,不会改动任何东西,适合反复执行。原文提到默认 DNS 为 10.0.2.3、默认 IP 为 10.0.2.15,这两个值就是 avd 网络模型里的固定角色:10.0.2.3 相当于模拟器内部的 DNS 服务,10.0.2.15 是模拟器自己拿到的地址。把它们记下来,后面改完要对比。如果grep提示命令不存在,说明该镜像精简了 toybox 工具集,直接跑全量getprop人工找也行。
3.2 setprop 修改 DNS:net.dns1 的写法与参数含义
确认完当前值,就可以落值了。改 DNS 用setprop net.dns1,把值换成宿主机所在网络实际使用的 DNS 地址。原文示例是 192.168.5.1,这个地址要按你自己的网络环境替换,不能照抄。
# 将模拟器首选 DNS 指向宿主机所在网络的 DNS 地址 setprop net.dns1 192.168.5.1 # 部分镜像还会读取第二个 DNS,建议一并设置,避免解析只走单点 setprop net.dns2 192.168.5.1 # 回读确认写入生效 getprop net.dns1setprop的语法是setprop 键 值,键名固定,值必须是字符串形式。这里最容易错的是把 DNS 写成网关地址,两者不一定是同一个;另一个坑是值里带了多余空格,导致属性被截断。改完立刻getprop net.dns1回读,能返回新值才算写入成功。需要说明的是,setprop的改动在模拟器重启后会丢失,属于临时生效,适合调试期反复调整。
3.3 setprop 修改 IP:net.gprs.local-ip 与网段对齐
IP 的改法同理,键是net.gprs.local-ip,值要选一个和宿主机同网段、又没被占用的地址。原文示例 192.168.5.100,前提是宿主机在 192.168.5.0/24 网段。换到别的网段就要跟着换,比如宿主机是 192.168.1.x,这里就写 192.168.1.100 这类地址。
# 将模拟器地址改到与宿主机同一网段,末位选一个空闲地址 setprop net.gprs.local-ip 192.168.5.100 # 回读确认 getprop net.gprs.local-ip # 再整体看一遍 dns 与 ip,确认两个键都已是新值 getprop | grep -E "dns|local-ip"参数选择上有两点取舍:末位不要用 1(常被网关占用)、不要用 255(广播地址),也不要和宿主机或其他设备冲突。改完 IP 后,模拟器内部的部分服务可能需要重新拉起网络才会认新地址,如果发现 ping 不通,先退出 shell 再重新adb shell观察。和 DNS 一样,这个改动也是临时的,重启模拟器即恢复默认。
3.4 改完回读:一次 getprop 确认两个键都生效
原文第六步就是再次getprop验证。这一步别省,因为setprop偶尔会因为属性只读或权限不足静默失败,命令没报错但值没变。稳妥做法是分别回读两个键,再做一次整体过滤。
# 分别回读,最直观 getprop net.dns1 getprop net.gprs.local-ip # 整体过滤,确认没有旧值残留 getprop | grep -E "net.dns1|net.gprs.local-ip"如果回读还是旧值,先看当前 shell 是不是 root。部分镜像的net.*属性需要 root 权限才能写,普通 shell 下setprop会失败但不一定给出明显提示。可以尝试adb root后重新进入 shell,再执行一次 setprop。回读通过后,再去模拟器里打开浏览器或请求本地服务做实际连通性验证,属性值对不代表链路一定通,这一步留到最后一章细说。
4. 避坑与排查:adb 报错、属性不生效、重启丢失怎么救
4.1 现象:adb shell 报 error: device '(null)' not found
原因通常是 adb 服务端状态异常,设备列表里没有可用条目,常见于模拟器刚启动、adb 进程残留或端口被占用。解决方式是杀掉 adb 服务再重启,让它重新扫描设备。
# 终止当前 adb 服务进程 adb kill-server # 重新启动 adb 服务,触发设备重新枚举 adb start-server # 再次确认设备在线 adb devices执行完这三条,正常情况下adb devices会重新列出emulator-5554 device。如果仍然为空,检查模拟器是否真的启动完成,以及是否有其他程序占用了 adb 默认端口。这个报错原文已经点到,属于最高频的一类,先按这个顺序处理,别一上来就重装 SDK。
4.2 现象:提示 error: device offline
原因是模拟器进程在,但 adb 与它的握手没完成,多见于模拟器还在开机动画阶段就执行了 adb 命令。解决办法是等模拟器进入桌面后再操作;已经 offline 的,可以重启 adb 服务或重启模拟器。
# 先尝试重启 adb 服务 adb kill-server adb start-server # 若仍 offline,关闭模拟器后重新启动,等桌面出现再执行 adb devices判断标准很简单:adb devices输出里设备状态是device才算可用,offline一律先修连接。我一般会等模拟器桌面完全加载、能点开应用抽屉之后再跑 adb,能省掉大半 offline 报错。
4.3 现象:setprop 执行了但 getprop 还是旧值
原因有三类:当前 shell 权限不足、属性键名拼错、或者该镜像对net.gprs.local-ip不响应。排查顺序是先回读确认键名,再确认权限,最后换验证方式。
# 确认键名拼写,注意是 net.gprs.local-ip,不是 net.gprs.local_ip getprop net.gprs.local-ip # 尝试以 root 身份重进 shell 后再写 adb root adb shell setprop net.gprs.local-ip 192.168.5.100如果 root 后仍不生效,说明该镜像的网络模型不走这个属性,此时不要死磕,改用模拟器自带的网络设置或代理配置来达到联调目的。这一点属于版本差异,原文没展开,但实际踩到的人不少。
4.4 现象:改完当时能用,重启模拟器后全部恢复默认
原因是setprop写入的是运行时属性,不落盘,模拟器重启即重置。这不是故障,是机制。解决思路是把设置命令固化成脚本,每次启动模拟器后跑一遍。
# 保存为 set-emulator-net.sh,启动模拟器后执行一次 adb shell setprop net.dns1 192.168.5.1 adb shell setprop net.gprs.local-ip 192.168.5.100 adb shell getprop net.dns1 adb shell getprop net.gprs.local-ip把这段脚本放在项目工具目录里,团队里谁换机器都跑同一份,能避免“我这能用你那不能用”的扯皮。需要长期固定的场景,再考虑在镜像层面做持久化配置,但那已经超出这篇操作笔记的范围。
4.5 现象:属性都对了,模拟器还是上不了网
原因往往不在 IP 和 DNS 本身,而在宿主机网络、模拟器网络模式或目标服务监听地址。排查时先确认宿主机自己能访问外网,再确认模拟器 ping 网关是否通,最后看目标服务是否只监听了 127.0.0.1。
# 在模拟器 shell 内测试到网关的连通性 ping -c 4 192.168.5.1 # 回到宿主机,确认目标服务监听地址不是仅本地回环 netstat -ano | findstr :8080如果服务只监听 127.0.0.1,模拟器从别的地址访问自然不通,需要把服务改为监听 0.0.0.0 或宿主机网卡地址。这类问题容易被误判成 IP 没设对,实际是服务端绑定地址的问题,排查时按链路从下往上走,别只盯 setprop。
5. 装完怎么验证跑通:三条命令加一次真实请求
改完属性、回读通过,只能说明值写进去了,离“跑通”还差一步实际验证。我习惯按三层来验:第一层看 adb 连接是否稳定,第二层看模拟器内部属性是否为新值,第三层发一次真实网络请求看返回。三层都过,才算这套 IP 设置真正落地。
第一层,宿主机上执行设备枚举,确认状态是device而不是offline:
adb devices # 期望输出类似:emulator-5554 device第二层,进入 shell 回读两个核心键,并顺手看一眼路由:
adb shell getprop net.dns1 adb shell getprop net.gprs.local-ip adb shell ip routegetprop返回的应该是你刚写入的 DNS 和 IP;ip route能看到默认路由指向的网关,如果路由表里还是旧的 10.0.2.x 网关,说明地址改了但路由没跟着更新,需要重新拉起网络或重启模拟器再设一遍。
第三层,做一次真实请求。最轻量的方式是在模拟器里用浏览器打开一个内网服务地址,或者在 shell 里用ping加curl组合验证:
# 先确认能到网关 adb shell ping -c 4 192.168.5.1 # 再请求宿主机上的测试服务,端口按实际替换 adb shell curl -I http://192.168.5.1:8080ping通说明二层链路没问题,curl能拿到响应头说明应用层也通。如果ping通但curl不通,多半是服务端监听地址或防火墙的问题,回到 4.5 节排查。三层验证的顺序不要颠倒,先连接、再属性、后请求,出问题时能快速定位是哪一层断的。
还有一个容易被忽略的点:验证时用的地址要和 setprop 写入的地址一致,别一边设了 192.168.5.100,一边又去请求 10.0.2.15,那当然不通。我一般会把验证命令和设置命令写进同一个脚本,设完立刻验,避免中间手动改来改去。
血泪经验是,这套操作里最贵的不是命令本身,而是改完不验证、等联调时才发现没生效。从那以后我每次配完模拟器网络,都强制走一遍“adb devices → getprop 回读 → ping 加 curl 实请求”这三步,哪怕当时看着一切正常也不跳过。希望帮到你。
本文还有配套的精品资源,点击获取