☰
AVD模拟器IP设置详解:getprop/setprop与ADB命令实战
2026/10/15 6:23:13 网站建设 项目流程

简介:在 Android 开发与调试过程中,模拟器默认 IP 与宿主机不在同一网段,常常导致无法联调或访问互联网。这份 doc 文档正是一份面向初中级 Android 开发者的模拟器 IP 设置实操指南,围绕 adb 命令行工具提供从环境准备到参数生效的完整操作闭环。内容以六大步骤为主线:启动模拟器、执行 adb shell 指令、通过 getprop 查看 DNS 与默认 IP、利用 setprop 修改 DNS 和模拟器 IP 至电脑网段,并最终验证配置生效;同时针对 device not found、device offline 等常见 adb 报错给出重启服务的处理思路。阅读后可快速掌握通过命令行配置模拟器网络属性的核心方法,也可作为日常测试与联调遇到网络连通难题时的排错参考。资源仅含 1 个 doc 文件,压缩包大小约 47KB,内容精炼集中,适合开发者快速查阅。已有 2148 人学习下载,是入门 Android 模拟器网络配置时值得参考的资料。

1. 模拟器IP和电脑不在一个网段:调试里的第一道坎

做 Android 开发,模拟器几乎人人必装,但 AVD 第一次跑起来就会撞上一个反直觉的局面:电脑在 192.168.1.x 网段,模拟器自己却是 10.0.2.x,两边互相访问不通,应用里连宿主机服务一直超时,连个网页有时都打不开。这不是代码写错了,是模拟器默认走了 NAT 虚拟网络,IP 和 DNS 都是虚拟网段内部的地址。这份《Android及avd模拟器ip设置详细操作.doc》就是把网络问题拆成几条可执行的 adb 命令:用 getprop 读当前 DNS 和 IP,再用 setprop 改成和电脑同网段,顺带处理两个最常见的 adb 报错。适合刚接触 adb 的新手,也适合被模拟器网络折腾过、想弄清 setprop 到底改了什么的老手。

2. 模拟器网络是NAT不是物理网卡:10.0.2.x背后的地址分配逻辑

模拟器跑起来以后,你看到的 IP 不是随机分配的,它来自一套固定的虚拟网络拓扑。原生 AVD 基于 QEMU 虚拟化,网络默认采用用户态 NAT 模式:不给模拟器分配宿主机物理网卡上的地址,而是在模拟器进程里维护一条虚拟链路,所有进出模拟器的数据包都经过一个虚拟网关转发。这一设计决定了默认 IP 永远落在 10.0.2.x 网段,也决定了你直接在宿主机上用 ipconfig 看不到模拟器的地址。

2.1 虚拟网络里的网关照单:网关、DNS、宿主机、设备各占哪个地址

这套虚拟网络把地址规划得很固定。每次冷启动模拟器,地址表基本不变,理解这张表再看文档里的 setprop 命令,就能明白为什么改的是那两个 key 而不是别的:

地址角色说明
10.0.2.1虚拟网关模拟器默认路由,出网流量统一交给它转发
10.0.2.2宿主机映射模拟器里访问这个地址等于访问宿主机的回环地址
10.0.2.3虚拟 DNS模拟器默认域名服务器,域名解析请求由它转发给宿主机
10.0.2.15模拟器自身虚拟网络分配给设备的地址,就是 getprop 里看到的默认 IP

NAT 模式被定成默认,核心原因只有一个:零配置。模拟器一启动就能拿到地址、能出网,不占用局域网里的真实 IP,也不会干扰宿主机所在网段的其他设备。代价也很明显——局域网里的其他机器看不见模拟器,模拟器访问宿主机网段内的服务时需要走 10.0.2.2 映射或者手工指定地址,这正好是文档要解决的痛点。

我遇到过不少开发者把 10.0.2.15 当成模拟器的固定 IP,其实它是虚拟 DHCP 分出来的地址。QEMU 的用户态网络内置了一个简易 DHCP 服务,每次网络启动时给虚拟网卡分配 10.0.2.15。这也是文档强调“默认 IP 为 10.0.2.15”的原因,它不是写在某个配置文件里的静态值。改掉这个值要小心,因为有些系统级服务在启动时已经把 10.0.2.15 写进了路由和 socket 绑定,光靠 setprop 改不动内核态的东西。

理解了这个布局,再看“让模拟器和电脑一个网段”这件事,本质就一句话:把模拟器侧看到的 DNS 和自身地址,从虚拟网络的固定值改写成宿主机所在网段的值,让调试双方的网络身份对齐。至于能不能真正通,取决于系统里哪些组件还在读这些属性,这就引出了 2.2 的问题。

2.2 getprop和setprop:修改的是系统属性,不是网卡配置

Android 有一套全局属性系统,开机时从镜像里的 default.prop、build.prop 以及内核启动参数里加载一批 key=value,放进一个共享内存区域。应用和系统服务可以随时读取,必要时也可以写入。adb shell 里敲 getprop 就是读取这个区域的全部内容,setprop 就是写一条新值进去。这套机制有点接近 Linux 下 sysctl 的临时修改,但作用范围在用户空间,不是真正去改 eth0 网卡接口。

文档里的两条核心命令其实分两层含义。setprop net.dns1 是把域名解析服务器指向宿主机的 DNS;setprop net.gprs.local-ip 是把模拟器自身的地址改成和电脑同网段。后者那个属性名带着老式 GPRS 网络的印记,说明这套做法诞生于 Android 还很早期的年代,当时网络服务读取的就是这些属性。到了新版 Android,DNS 解析由 netd 统一管理,net.gprs.local-ip 在不少系统里成了遗留字段,setprop 写进去未必有人消费。

所以在复现之前先把期望值放平:这份文档的操作在旧版本模拟器、定制 ROM 上通常立竿见影,在较新的模拟器上可能改完 getprop 回读正常,但实际链路没变化。遇到这种情况不用怀疑命令敲错了,直接跳到第 6 章换方案。接下来先按文档流程完整走一遍,把能改的、能验证的都在命令行里做到位。

新版 Android 上 setprop 还会碰到属性权限问题。系统引入了 property_contexts 和 SELinux 策略,控制哪些进程能写哪些属性,普通 shell 用户去改 net. 开头的属性,可能直接收到 permission denied,或者命令敲下去没有报错但值没变。这点先记住,第 5 章避坑部分会具体展开。

3. 完整复现:从adb连接到setprop改DNS和IP

这份文档的核心价值就是“照着敲就能改完”,但实际操作里最大的阻力不在 setprop 本身,而在能不能顺利连上 adb。这一章我按文档的六步走一遍,每一步都给出命令、输出解读和参数说明。

3.1 环境确认与adb连接:先解决device not found

先准备三样东西:一个已经启动的模拟器、Android SDK 的 platform-tools 目录、一个 cmd 窗口。启动模拟器后,桌面会出现设备窗口,但 adb 未必马上能识别,需要先确认服务状态。打开 cmd,进入 SDK 所在位置,常见路径是%LOCALAPPDATA%\Android\Sdk\platform-tools,如果你用 IDE 内置的 SDK,路径可能不同,以实际安装位置为准。

# 1. 确认 adb 可执行文件存在且版本正常 adb version # 2. 列出当前所有连接的设备,确认模拟器已被识别 adb devices # 3. 进入模拟器的 shell 环境 adb shell

adb devices的输出里,序列号一列通常是emulator-5554这种格式,状态列显示device表示连接正常,显示offline或unauthorized则说明没准备好。第 3 步的adb shell会进入一个 Linux shell 提示符,后续的 getprop、setprop 都在这个环境里执行,不是在 Windows 的 cmd 里直接敲。这两者容易混淆,文档原文写的是“进入 shell 窗口后执行”,就是这个意思。

如果第一步就报error: device '(null)' not found,说明 adb 服务没找到目标设备。这是 adb 服务状态异常,不是模拟器本身坏了,按文档给的办法处理即可:

# 杀掉 adb 服务进程 adb kill-server # 重新启动 adb 服务 adb start-server # 再次确认设备 adb devices

kill-server和start-server是一对组合,杀掉再拉起会让 adb 重新扫描所有设备节点。执行完再回到adb shell,绝大多数情况下设备就能识别。如果还是找不到,确认模拟器窗口是真的完全启动完成,而不是还停在启动动画阶段。

3.2 读取当前属性:getprop按关键字过滤DNS与IP

进入 shell 后,直接敲 getprop 会刷出几百行系统属性,里面大部分跟网络无关。为了只看网络相关值,我一般用 grep 过滤关键字,Windows 下如果在 cmd 外层操作,则用 findstr 替代:

# 在 adb shell 内执行,只显示包含 net 的属性行 getprop | grep net # 单独读 DNS 配置 getprop net.dns1 # 单独读模拟器自身 IP 属性 getprop net.gprs.local-ip

输出里能看到[net.dns1]: [10.0.2.3]和[net.gprs.local-ip]: [10.0.2.15],这就是文档说的模拟器默认配置。这两个值一个决定域名解析往哪走,一个决定模拟器对外宣称的本地地址。如果 getprop 输出里根本没有这几个属性,说明该镜像的网络服务不读这套属性,后面改了也白改,直接跳到验证环节看效果。

这里有个细节容易翻车:如果你在 Windows cmd 里直接写adb shell getprop | grep net,管道符会被 cmd 截获,grep 是在 Windows 侧执行的,结果通常是“grep 不是内部或外部命令”。正确做法是先adb shell进入交互 shell,再执行带管道的那条命令,或者写成adb shell "getprop | grep net"让整条命令在模拟器内解析。

3.3 执行修改与生效验证:setprop带参数改两个关键属性

修改前先确认电脑自己的网络参数。Windows 下执行 ipconfig /all,记下 IPv4 地址和 DNS 服务器地址。文档里用的是 192.168.5.1 这个网段,实操时以你电脑实际的局域网网段为准,不要照抄。

# 在 adb shell 内执行,把 DNS 改成电脑的 DNS 服务器 setprop net.dns1 192.168.5.1 # 把模拟器自身 IP 改到和电脑同一个网段 setprop net.gprs.local-ip 192.168.5.100 # 回读确认修改已写入属性区 getprop net.dns1 getprop net.gprs.local-ip

两条 setprop 命令没有顺序依赖,先改哪个都行。192.168.5.1 是示例,必须替换成 ipconfig 里看到的实际 DNS;192.168.5.100 同样要选一个当前网段内没有被占用的地址,别跟电脑或其他设备冲突。net.dns1只写了第一个 DNS,如果你的电脑配了多个 DNS,可以继续写setprop net.dns2 192.168.5.2补齐,模拟器解析域名时会按顺序尝试。

回读这一步不能省。文档第六步再次执行 getprop 就是为了确认属性写入成功,而不是看 ping 或者看界面。属性写入后,界面上的图标和设置页可能不会同步变化,这是正常的,这套命令走的是系统属性通道,不走图形界面的网络设置。

3.4 补充验证:ping网关与域名解析是否真的通

文档停在 getprop 回读就结束了,但按我的血泪经验,属性写入和实际网络链路是两回事,最好加一步连通性验证。在 adb shell 里执行:

# 在 adb shell 内执行,ping 电脑所在网段的网关 ping -c 3 192.168.5.1 # 确认虚拟 DNS 是否还能响应 ping -c 3 10.0.2.3

第一条 ping 宿主机的网段 IP,通说明模拟器到宿主机网段的路径基本可用;第二条 ping 10.0.2.3,通说明虚拟 DNS 转发还活着。如果两条都通,但应用里仍然打不开网页,那通常不是 IP 配置的问题,而是代理设置或端口访问策略的问题,别在 setprop 上继续耗时间。

如果 ping 提示命令不存在,说明这个镜像里没带 ping 工具,改用curl或者直接在应用层测试连通性。部分精简系统镜像连 curl 也没有,这时候就只能回到 getprop 回读作为验证依据。

4. 重启就失效的真相:临时属性与自动化复现方案

文档里的操作步骤确实能改,但它有个隐藏前提:这些修改只在当前这次开机周期内有效。模拟器一重启,一切回到解放前。这一章把原理讲透,再给一个减少重复劳动的脚本方案。

4.1 为什么重启后IP回到10.0.2.15:属性是内存态配置

setprop 写入的属性存放在共享内存区域,相当于运行时的临时配置,不会持久化到模拟器镜像里。模拟器下次冷启动,系统重新从 default.prop、build.prop 以及内核 cmdline 加载初始值,之前用 setprop 写入的新值全部丢失。这和 Linux 下用 sysctl 临时调参后重启恢复默认是同一个道理。

所以文档这套方案适合“当次联调”:模拟器开着,改完,测完,关机,下次需要再改。它不是一劳永逸的网络配置方案。如果项目每天都开着模拟器联调,可以把这套命令封装成脚本,每次开机后跑一遍,省得反复手敲。

另外要注意,模拟器如果做了快照(Snapshot)保存,重启后会恢复到快照时的属性状态。如果你在快照保存前改了 IP,之后每次从快照恢复,属性值可能还保留着;但如果是完整冷启动,就会回到默认值。这个差异很容易让人误判“为什么有时候重启后改了、有时候没改”。

4.2 参数化批处理脚本:一条命令重放全部设置

把命令写进 Windows 批处理脚本,每次双击执行即可。脚本里把 IP 和 DNS 提取成变量,换网段时只改两处,不用再翻命令历史:

@echo off setlocal set DEVICE_IP=192.168.5.100 set DNS_SERVER=192.168.5.1 adb wait-for-device adb shell setprop net.dns1 %DNS_SERVER% adb shell setprop net.gprs.local-ip %DEVICE_IP% adb shell getprop net.dns1 adb shell getprop net.gprs.local-ip endlocal

脚本里wait-for-device是关键,它会让 adb 一直等待,直到有设备连上再继续往下执行,避免模拟器还没完全启动完就执行 setprop,导致命令落在空设备上。变量放最前面,以后 DHCP 重新分配了电脑 IP,只需要改DNS_SERVER和DEVICE_IP两行。注意批处理文件保存时保持 GBK 编码,否则中文注释会乱码,或者干脆把注释写成英文。

这里用adb shell setprop ...的写法,是一次性执行单条命令后退出 shell,和 3.1 里进入交互式 shell 不同。如果想在一个 adb shell 调用里执行多条命令,用引号包起来,比如adb shell "setprop net.dns1 192.168.5.1 && getprop net.dns1"。

4.3 多模拟器同时管理:用序列号隔离adb操作

开了多个模拟器时会发现,直接adb shell会报“more than one device”,因为 adb 不知道该发给谁。用adb devices查看序列号,再用-s参数指定目标设备。我一般这样处理:

# 列出所有设备及序列号 adb devices # 指定序列号执行修改 adb -s emulator-5554 shell setprop net.dns1 192.168.5.1 adb -s emulator-5556 shell setprop net.dns1 192.168.5.1 # 批量操作:对每个设备执行同一组命令 for %d in (emulator-5554 emulator-5556) do adb -s %d shell setprop net.dns1 192.168.5.1

-s参数后面跟的是设备序列号,每次执行命令都要带着,没有默认设备一说。批量操作时在 cmd 里用for循环,但要注意 cmd 的 for 循环变量和 bat 脚本里的写法有区别,脚本里要写%%d,命令行交互里写%d。多模拟器场景下推荐先adb devices确认所有设备都处于device状态再批量执行,否则个别设备离线会让命令静默失败。

5. 避坑指南:模拟器IP设置中常见的错误和排查路径

文档只处理了 device not found 和 device offline 两个报错,实际使用中还会遇到权限、版本不生效、改完断网等状况。这一章按现象到原因到解决的方式,把最常见的几个坑逐个过一遍。

5.1 三种adb报错:not found、offline与权限拒绝

错误提示含义处理路径
error: device '(null)' not foundadb 服务没有找到目标设备adb kill-server 后 adb start-server,再 adb devices
error: device offline设备状态未就绪或 adb 通道不稳定等待模拟器完全启动,仍不行则重启 adb 服务和模拟器
setprop 报 permission denied当前 shell 没有该属性的写权限先执行 adb root,或更换允许 root 的谷歌 API 镜像

第一条是文档重点讲过的:adb 服务僵死,杀掉重启基本能解决。第二条 offline 的坑在于模拟器启动动画没走完时很容易出现,尤其是机器配置一般、模拟器冷启动要几十秒的环境。我一般先等 30 秒再 adb devices,而不是一启动就着急连。第三条权限问题在新镜像上非常普遍,执行adb root后 adb 会以 root 身份重启设备端服务,再进 shell 执行 setprop 就能绕过大部分属性权限限制。注意adb root只对开放 root 的镜像有效,Play Store 版本镜像默认不允许,会明确返回adbd cannot run as root in production builds。

5.2 改完不生效的两种情形:版本限制与属性作用范围

现象:getprop 回读确实返回了新值,但模拟器访问宿主机服务还是超时,域名解析也还是老样子。这类问题最迷惑人,因为命令执行成功、属性也写进去了,网络实际行为却一点没变。

原因有两类。第一类是新版 Android 的网络栈不再消费这些属性,DNS 由 netd 守护进程统一管理,setprop 写进去的 net.dns1 根本没被读取;net.gprs.local-ip 在多数新版系统里更是纯遗留字段。第二类是网络接口的实际地址和路由表没变,setprop 改的是用户空间属性,内核里 eth0 的地址、路由表的默认网关都还是原来的值,socket 通信时源地址依然是 10.0.2.15。

解决思路分两步:先确认系统版本和镜像类型,如果用的是 API Level 比较高的模拟器,就别在这条路上继续耗,换第 6 章的方法;如果确实还要验证属性是否被消费,用ip addr看 eth0 的实际地址,用ip route看默认路由,两者对比就知道属性值和实际链路差在哪。

5.3 改完反而断网的排查:网关与DNS回退策略

现象:DNS 和 IP 都改成宿主机网段后,模拟器反而彻底上不了网,连之前的 NAT 通路也断了。这类翻车现场在初学者里很常见,因为只改了两个属性,没动默认网关。

原因在于模拟器的默认路由仍然指向 10.0.2.1 那个虚拟网关。你把 DNS 和本地地址改到了 192.168.5.x,但出网流量还是先交给 10.0.2.1,这个虚拟网关并不认识 192.168.5.x 网段的包,转发就断了。另一种可能是 DNS 地址写错,比如把电脑的本地保留地址当 DNS 写进去,解析直接失败。

解决的优先级我建议这样:先把 DNS 改回 10.0.2.3,确认域名解析恢复正常,再判断是否真的需要改 DNS。如果你的目标只是让模拟器访问宿主机的某个服务,优先用 10.0.2.2 这个内置映射地址,不需要大动干戈把网段改成一致。如果确实需要同网段通信,还要额外确认默认网关是否可达,以及目标服务是否监听了对应网卡的端口。

6. 当setprop失效时:端口映射和桥接的正确用法

如果你的模拟器跑在新版系统上,setprop 这条路走不通,别犹豫,直接换端口映射。adb 自带两条反向命令,能绕开 IP 网段问题:adb reverse把模拟器里的端口转发到宿主机,模拟器访问 localhost 上的端口时,流量会直接送到宿主机的对应端口;adb forward则反过来,宿主机访问本机端口时转发到模拟器。联调场景里 reverse 更常用,因为大部分时候是模拟器要访问电脑上的服务。

# 模拟器访问 localhost:8080 时,转到宿主机的 8080 端口 adb reverse tcp:8080 tcp:8080

这条命令的关键参数是 tcp 端口对,前一个是模拟器侧端口,后一个是宿主机侧端口。两边一致时只写一个端口号也行,但我习惯显式写全,避免混淆。同理,如果想从电脑直接访问模拟器里的服务,用 forward 反方向转。这种方式不关心模拟器内部 IP 是多少,只要 adb 链路通,端口就能通。

如果你的场景是多人协作,模拟器必须作为独立设备出现在局域网里,端口映射也解决不了,那就只能换网络模式。原生 AVD 创建时可以选择网络配置,部分第三方模拟器提供桥接模式,前提是在创建或启动前设置,不是运行时改属性。桥接模式会让模拟器直接向局域网申请 IP,这时反而需要确认 DHCP 地址池充足、没有 IP 冲突,比 NAT 模式的运维成本高不少。

我现在拿到一个模拟器联调需求,第一反应不是 setprop,而是先想清楚目标服务在哪一侧、能不能用端口映射解决;只有碰到老项目、老镜像不得不改属性时,才会把文档里那套命令完整走一遍。从那以后我每次改完都会强制做一次 ping 验证,不再只信 getprop 回读,这个习惯救了我好几次。这套文档的完整操作步骤值得留一份在本地,遇到旧环境时它就是后悔药。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询