简介:这份文档面向Android开发初学者与需要联调模拟器网络环境的开发者,聚焦AVD模拟器与电脑不在同一网段、无法联网或通信失败的问题,给出从启动模拟器到验证生效的完整IP设置操作指引。资源包共1个文件,为doc格式的图文操作文档,压缩包约47KB,体积轻便,适合随查随用。文档围绕adb命令行工具展开,涵盖启动模拟器、进入platform-tools执行adb shell、用getprop读取默认DNS与IP、通过setprop修改DNS和IP、再次getprop验证结果等环节,并针对“device not found”“device offline”等常见报错给出重启adb进程的排错思路,配有操作截图辅助理解。目前已有2149人学习,说明该问题在开发实践中较为普遍。读者可据此快速完成模拟器网络配置,减少调试环境搭建的试错成本。
1. 模拟器 IP 和电脑不在一个网段:这份文档把 adb 改 IP 的完整链路拆开了
做 Android 开发的人几乎都撞过同一个场景:模拟器起来了,App 装上了,日志也连上了,可一到联调就卡住——模拟器访问不了电脑上跑的本地服务,电脑也 ping 不通模拟器,抓包工具里两边像隔了一堵墙。根因往往不是代码,而是 AVD 默认落在10.0.2.x这个 NAT 网段里,和电脑的192.168.x.x天然不通。这份《Android 及 avd 模拟器 ip 设置详细操作.doc》就是围绕这个痛点写的:从启动模拟器、进platform-tools跑adb shell,到用getprop读默认 DNS 和 IP,再用setprop把net.dns1、net.gprs.local-ip改到电脑同网段,最后回读验证。它适合正在做本地联调、接口测试、抓包排查的 Android 开发者,尤其是被模拟器网络折腾过一轮、想找一份能照着敲的操作底稿的人。下面我按这份文档的链路,把每一步为什么这么做、参数怎么填、哪里会翻车讲透。
2. 先把 adb 通道打通:platform-tools 定位与设备状态判定
改模拟器 IP 的所有动作都发生在adb shell里,所以第一步不是改 IP,而是确认 adb 能稳定连上模拟器。这一步看着简单,实际是后面所有报错的源头。文档里把「进 platform-tools 目录 → 执行 adb shell」放在最前面,顺序是对的,但没展开讲为什么必须先解决设备状态。
2.1 为什么必须先进 platform-tools 目录
adb不是系统自带命令,它是 Android SDK 里的一个可执行文件,默认躺在 SDK 根目录下的platform-tools里。你在任意 cmd 窗口直接敲adb,大概率报「不是内部或外部命令」,这不是 adb 坏了,是 PATH 没配。两种做法:一是每次cd进目录再执行,适合临时用;二是把platform-tools加进系统环境变量 PATH,适合长期开发。我一般推荐后者,因为改 IP 这种操作往往要反复试几轮,每次切目录很烦。
# 方式一:临时进入目录(路径按自己 SDK 实际位置替换) cd C:\Users\YourName\AppData\Local\Android\Sdk\platform-tools # 确认 adb 可用,能打印版本号说明通道没问题 adb version # 方式二:永久加入 PATH 后,任意目录直接验证 adb devices上面第一段是临时方案,cd的路径要换成你本机 SDK 的真实位置,常见在用户目录的AppData\Local\Android\Sdk下,也可能是 Android Studio 安装时自定义的路径。adb version用来确认可执行文件本身没损坏;adb devices是更关键的一步,它列出当前被 adb 识别的设备,模拟器正常时应该出现一行emulator-5554 device。注意末尾那个状态词:device才是可用,offline和unauthorized都不行。参数上没什么可调的,adb devices加-l会多打印设备型号和传输方式,排查多设备时有用。
2.2 device not found 与 device offline 是两回事
文档里提到两个错误:error: device '(null)' not found和error: device offline,并给了adb kill-server+adb start-server的解法。这两个错误的成因其实不同,混在一起处理容易白折腾。
device '(null)' not found通常意味着 adb 服务端状态错乱——可能是之前连过真机、模拟器重启过、或者 adb 进程卡在半死状态,服务端记着一堆失效的连接。这时候重启 adb 服务端是对的,因为它会清空连接表重新扫描。
# 杀掉当前 adb 服务端进程 adb kill-server # 重新拉起服务端,它会重新枚举所有设备 adb start-server # 再确认一次设备列表 adb devices这三条命令的逻辑是:kill-server结束后台的 adb daemon,start-server重新启动并触发设备扫描,devices验证结果。参数上没有额外开关,但要注意执行顺序不能颠倒,先 kill 再 start。如果重启后adb devices还是空的,问题就不在 adb 而在模拟器本身——模拟器没真正启动完,或者 AVD 的 adb 端口被占用。
device offline则是另一码事:adb 看得见这个设备,但握手没完成。最常见原因是模拟器还在开机动画阶段,系统服务没起来,adb 自然连不上。文档说「启动模拟器即可」,方向对,但要补一句:等模拟器完全进入桌面、状态栏出现后再执行adb devices,别在开机过程中反复敲命令。还有一种情况是模拟器进程僵死,界面上看着开着,实际系统已经挂了,这时候光等没用,得在 AVD Manager 里冷启动(Cold Boot)一次。
提示:改 IP 前先确保
adb devices稳定输出device状态,否则后面adb shell里的setprop全是空谈。
2.3 进入 shell 的正确姿势与多设备歧义
设备状态正常后,adb shell进入模拟器的 Linux shell 环境,后续getprop、setprop都在这里面执行。单设备时直接敲就行;如果你同时连着真机和模拟器,adb shell会报more than one device/emulator,必须用-s指定序列号。
# 单设备直接进 shell adb shell # 多设备时先看序列号,再指定目标 adb devices adb -s emulator-5554 shell-s后面的emulator-5554就是adb devices第一列打印的序列号,模拟器一般是emulator-5554、emulator-5556这种递增形式。这一步的参数意义在于把命令精确投递到目标设备,避免改错对象。进 shell 后提示符会变成generic_x86:/ #或类似形式,说明已经在模拟器系统内部,此时敲的都是 Android 的 shell 命令,不是 Windows 命令,这点新手容易混。
3. getprop 读默认网络参数:10.0.2.3 和 10.0.2.15 从哪来
进到 shell 之后,文档让你先跑getprop看系统属性,从中读出默认 DNS10.0.2.3和默认 IP10.0.2.15。这一步是整个改 IP 流程的「基线测量」,不先看清现状就动手改,改完也不知道对不对。
3.1 getprop 输出太长,怎么精准捞出网络相关项
getprop不带参数会把模拟器几百条系统属性全打出来,翻起来费劲。实际排查时我一般直接过滤网络相关的键,效率高得多。
# 全量输出(文档原始做法,用于整体了解) getprop # 只看 DNS 相关属性 getprop | grep dns # 只看 IP / 网络接口相关属性 getprop | grep -E "net\.|ip|gprs"getprop本身无参数,输出格式是[key]: [value]一行一条。管道接grep是 shell 层的过滤,grep dns会命中net.dns1、net.dns2这类键;grep -E开扩展正则,一次匹配多个关键词。这里要注意,不同 Android 版本的属性键名不完全一致,net.dns1在多数模拟器镜像里存在,但新版本可能走net.dns1之外的解析路径,所以「读得到」不等于「改了一定生效」,后面验证环节必须回读。
3.2 10.0.2.3 与 10.0.2.15 的来历
这两个地址不是随便定的,是 AVD 默认 NAT 网络的标准配置:10.0.2.15是模拟器虚拟网卡的地址,10.0.2.3是这套 NAT 里的 DNS 服务地址,网关通常是10.0.2.2,它映射到宿主机的回环。也就是说,模拟器默认活在一个封闭的10.0.2.0/24小网络里,出网靠 NAT 转发。这解释了为什么模拟器能上网却和电脑不同网段——它压根不在你电脑的局域网里,中间隔着一层虚拟 NAT。
理解这一点,才能明白文档改 IP 的本质:它不是真的把模拟器接进你的物理局域网,而是通过setprop覆盖系统属性里的地址记录,让模拟器内部认为自己在192.168.5.x网段。这个区别很关键,直接决定了后面哪些场景能通、哪些通不了。
| 属性键 | 默认值 | 含义 | 是否可直接改 |
|---|---|---|---|
net.dns1 | 10.0.2.3 | 主 DNS 地址 | 可 setprop 覆盖 |
net.gprs.local-ip | 未设或空 | 本地 IP 记录 | 可 setprop 覆盖 |
| 虚拟网卡实际地址 | 10.0.2.15 | NAT 分配的接口地址 | 属性改不动,需靠 NAT 或重定向 |
表格最后一行是血泪经验:setprop改的是属性,不是网卡。模拟器真实网卡地址仍由 NAT 决定,属性只是给上层应用读的一个值。所以文档这套方法在「让 App 读到期望的 IP」这类场景有效,在「让电脑真正 ping 通模拟器」这类场景未必有效,得配合端口转发或反向代理,这点后面避坑章会展开。
3.3 记录基线,方便改完对比
动手前把关键几项抄下来或存文件,改完再读一次做 diff,是最省事的验证方式。
# 改之前存一份基线 getprop | grep -E "net\.dns1|net\.gprs\.local-ip" > /sdcard/before.txt # 改之后存一份 getprop | grep -E "net\.dns1|net\.gprs\.local-ip" > /sdcard/after.txt # 对比差异 diff /sdcard/before.txt /sdcard/after.txt>是重定向写文件,/sdcard/是模拟器内部存储,diff逐行比对。这套动作的价值在于:setprop有时会静默失败(权限或键名问题),肉眼扫getprop长输出容易漏,diff 一跑差异一目了然。参数上grep -E的正则里\.是转义点号,别写成通配。
4. setprop 改 DNS 与 IP:两条命令背后的参数与生效边界
基线清楚了,就进入文档的核心两步:setprop net.dns1 192.168.5.1改 DNS,setprop net.gprs.local-ip 192.168.5.100改 IP。命令本身很短,但参数怎么选、为什么是这两个键、改完为什么有时不生效,才是真正要讲清的部分。
4.1 setprop 的语法与权限前提
setprop的语法是setprop <key> <value>,两个参数:属性键和值。它写的是 Android 的 property 系统,普通 shell 用户对多数net.*键有写权限,但个别键受 SELinux 或属性上下文限制,会报failed to set property。
# 改 DNS 为电脑所在网络的 DNS(示例用 192.168.5.1) setprop net.dns1 192.168.5.1 # 改本地 IP 记录到电脑同网段(示例用 192.168.5.100) setprop net.gprs.local-ip 192.168.5.100 # 若报权限失败,可尝试切 root(仅 userdebug/eng 镜像可用) su setprop net.dns1 192.168.5.1第一、二条就是文档原命令,值要换成你电脑实际网段的地址:DNS 填你电脑ipconfig /all里看到的 DNS 服务器,IP 填一个同网段内没被占用的地址。第三条的su是兜底,模拟器镜像如果是 userdebug 或 eng 版本通常能拿到 root,正式 user 镜像拿不到,这时只能换镜像或接受失败。参数选择上有个原则:192.168.5.100这种尾号要避开路由器 DHCP 池的高频分配段,否则容易和别的设备撞地址,虽然属性层面不冲突,但联调时容易自己把自己绕晕。
4.2 为什么是 net.dns1 和 net.gprs.local-ip 这两个键
net.dns1是 Android 早期就存在的 DNS 属性键,很多网络库和系统组件会读它做域名解析,改它等于告诉模拟器「解析域名去问这个地址」。net.gprs.local-ip则是一个历史遗留的本地 IP 记录键,名字里的 gprs 是移动网络时代的产物,但在模拟器场景下常被拿来承载「我期望的本地地址」。文档选这两个键,是因为它们在多数模拟器镜像里可写、可读、可验证,属于成本最低的改法。
但要清楚边界:这两个键不是「设置网卡地址」的官方接口。真正改网卡地址要走ifconfig/ip命令,而模拟器的 NAT 网卡通常不允许随意改地址,改了也可能被 NAT 层覆盖回去。所以文档这套setprop方案,本质是「改属性让上层读到期望值」,适合 App 内读取 IP、拼接回调地址、做本地服务发现这类逻辑;不适合指望它把模拟器真正接入物理局域网。这个认知差是后面最多人翻车的地方。
4.3 改完必须回读验证,别信命令没报错
setprop不报错不代表生效,属性系统有时会接受写入但被后续服务覆盖。文档第六步「再次 getprop 验证」是对的,我把它做得更细一点。
# 回读两个关键属性,确认值已变 getprop net.dns1 getprop net.gprs.local-ip # 顺带看接口真实地址,和属性值对比 ip addr show # 验证 DNS 是否真的能解析(需要模拟器有出网能力) ping -c 2 www.example.com前两条直接读单键,输出就是当前值,最直观。第三条ip addr show看的是网卡真实地址,你会发现它大概率还是10.0.2.15,和属性里的192.168.5.100不一致——这不是失败,是前面说的属性与网卡分离,属正常现象。第四条ping是端到端验证,-c 2限制发两个包就停。如果 ping 域名不通但 ping IP 通,说明 DNS 没真正生效;如果都通,说明属性改法在这台模拟器上起了作用。参数上-c别省,不然 ping 会一直刷。
注意:
setprop的修改在模拟器重启后会丢失,属于临时生效。需要持久化得写进启动脚本或改用其他网络配置方式,文档没提这点,实际用的时候要心里有数。
5. 避坑与排查:五条改 IP 路上真会遇到的坑
这套操作步骤不多,但每一步都有翻车的可能,而且报错信息往往不指向真正原因。下面五条是我按「现象 → 原因 → 解决」整理的实战记录,照着排能省不少时间。
5.1 现象:setprop 执行成功,getprop 回读还是旧值
原因通常是属性被系统服务覆盖,或者键名在当前镜像里根本不被网络栈读取。部分新版本模拟器镜像对net.dns1的读取路径已经变化,写了也没人用。解决:先确认镜像版本,换用net.dns1之外实际生效的解析配置;或者改用adb shell settings相关命令配置网络;再不行就在 App 层用代码指定 DNS,绕开系统属性。回读不一致时不要反复重敲同一条命令,先判断是「没写进去」还是「写进去没人读」。
5.2 现象:改了 IP 属性,电脑还是 ping 不通模拟器
原因是属性不等于网卡,模拟器仍在 NAT 后面,物理上就没进你的局域网。解决:如果目标是电脑访问模拟器里的服务,用adb forward tcp:本地端口 tcp:模拟器端口做端口转发,这是最稳的路子;如果目标是模拟器访问电脑上的服务,用10.0.2.2这个 NAT 网关地址指向宿主机,比改 IP 属性可靠得多。把「改属性」当成「改网络拓扑」是最大的误解。
5.3 现象:adb devices 一直 offline,kill-server 也没用
原因是模拟器系统没启动完,或者 AVD 快照损坏导致系统卡在半启动状态。解决:先在 AVD Manager 里执行 Cold Boot 冷启动,跳过快照;仍不行就 Wipe Data 清一次用户数据。别在 offline 状态下反复adb shell,那只会不断报错。判断是否启动完,看模拟器界面是否进入桌面、状态栏是否出现,比看命令行更直接。
5.4 现象:多设备环境下 setprop 改到了真机上
原因是adb shell没带-s,adb 在多设备时行为不确定,可能默认投给某一台。解决:养成习惯,只要adb devices输出超过一行,所有adb shell命令都带-s emulator-5554。改完在目标设备上回读确认,别在电脑侧看日志就以为成了。这个坑不常见但一旦踩中,改错真机网络配置的后果比改错模拟器严重得多。
5.5 现象:DNS 改了,模拟器还是解析不了域名
原因是模拟器本身没有出网能力,或者改的 DNS 地址在你的网络里不可达。解决:先ping 10.0.2.2确认 NAT 网关通不通,再ping你填的 DNS 地址确认可达,最后才怀疑解析配置。如果宿主机本身走的是公司内网 DNS,模拟器 NAT 未必能转发到,这时填公共 DNS 反而更容易通。排查顺序永远是「物理连通 → 地址可达 → 解析配置」,倒过来查会绕远路。
6. 把改 IP 固化成可复用脚本:一次写对,后面少敲
单次改 IP 敲几条命令不难,难的是每次换模拟器、换网段都要重来一遍,还容易漏步骤。我的做法是把整套流程写成一个批处理脚本,参数化网段,跑一次完成「检查设备 → 读基线 → 改属性 → 回读验证」四件事。这样既减少手误,也把前面讲的验证环节强制带上,不给「改了没验证」留空子。
@echo off REM 用法:set_avd_ip.bat 192.168.5.1 192.168.5.100 set DNS=%1 set LOCALIP=%2 set SERIAL=emulator-5554 REM 1. 确认设备在线 adb -s %SERIAL% get-state | findstr "device" >nul if errorlevel 1 ( echo 设备未就绪,先检查模拟器状态 exit /b 1 ) REM 2. 改 DNS 与本地 IP 属性 adb -s %SERIAL% shell setprop net.dns1 %DNS% adb -s %SERIAL% shell setprop net.gprs.local-ip %LOCALIP% REM 3. 回读验证,打印实际值 echo 当前 DNS: adb -s %SERIAL% shell getprop net.dns1 echo 当前本地 IP 属性: adb -s %SERIAL% shell getprop net.gprs.local-ip脚本里%1、%2是两个入参,分别接 DNS 和期望 IP,调用时set_avd_ip.bat 192.168.5.1 192.168.5.100即可。SERIAL写死成emulator-5554是为了演示,多开模拟器时改成变量传入更稳妥。get-state加findstr是前置守卫,设备不在线直接退出,避免后面一串命令全报错。最后两行回读是这套脚本的价值所在——它把「验证」变成了流程的一部分,而不是靠人记得去敲。
进阶一点,可以把回读结果和期望值做字符串比对,不一致就打印警告;也可以把adb forward的端口转发一并写进去,让「改属性」和「打通访问」两步合成一次执行。我一般还会在脚本末尾加一条adb -s %SERIAL% shell ip addr show,把真实网卡地址也打出来,提醒自己属性值和物理地址是两回事,别被属性骗了。
从那以后我每次动模拟器网络配置,都强制走一遍「先 getprop 存基线、再 setprop、最后回读加 ping 验证」的固定动作,哪怕只是改一个 DNS 也不省这一步,因为省下的那几秒,往往要用半小时排查来还。希望帮到你。
本文还有配套的精品资源,点击获取