You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android API 35中MockWebServer启动失败的原因及解决咨询

问题背景

我有一个基于API 34的应用,使用MockWebServer 5.0.0-alpha.12开展测试,仅在需Mock的测试中触发该服务,MockWebServer类在8080端口初始化,代码如下:

class MockedkWebServer {
...
 init {
  val mockServer = MockWebServer()
   mockServer.start(8080)
   ...
 }
 ...
}

该配置在API 34上运行正常,但在API 35设备上执行Mock测试时失败,调用mockServer.start(8080)启动MockWebServer1秒后抛出错误:

java.net.UnknownHostException: Unable to resolve host "localhost"; No address associated with hostname.

尝试在network_config.xml中添加部分IP地址后测试可运行但启动时仍可能失败,配置如下:

<domain-config cleartextTrafficPermitted="true">
    <domain includeSubdomains="true">localhost</domain>
    <domain includeSubdomains="false">10.0.2.2</domain>
    <domain includeSubdomains="false">10.0.2.3</domain> <!-- added -->
    <domain includeSubdomains="false">10.0.3.2</domain>
    <domain includeSubdomains="true">10.0.2.15</domain> <!-- added -->
    <domain includeSubdomains="true">10.0.2.16</domain><!-- added -->
  </domain-config>
问题成因
  • API 35网络管控升级:Android 14(API 35)对localhost域名解析、测试进程的网络访问权限做了更严格的限制,默认情况下可能阻止测试进程将localhost解析为环回地址,导致服务启动时无法找到对应主机。
  • MockWebServer预览版适配不足:使用的5.0.0-alpha.12是预览版本,未针对API 35的网络行为变更做充分适配,存在绑定地址或解析逻辑的兼容性问题。
  • 固定IP配置的局限性:手动添加的10.0.x.x系列地址是模拟器特定网关/内网地址,但API 35可能为测试进程分配随机环回地址,或网络命名空间与API 34不同,导致固定IP无法覆盖所有场景,出现偶发启动失败。
稳定解决方案

1. 绑定环回地址启动MockWebServer

直接使用系统环回地址启动服务,绕过localhost解析环节,从根源避免解析失败:

class MockedkWebServer {
...
 init {
  val mockServer = MockWebServer()
  // 绑定到环回地址,无需依赖localhost解析
  mockServer.start(InetAddress.getLoopbackAddress(), 8080)
   ...
 }
 ...
}

InetAddress.getLoopbackAddress()会返回当前系统的环回IP(通常是127.0.0.1或::1),确保服务能稳定绑定。

2. 升级MockWebServer到稳定适配版本

放弃使用alpha预览版,升级到官方最新的稳定版本(如5.x正式版及以上)。正式版本会针对API 35的网络变更做适配修复,解决版本兼容性导致的启动问题。

3. 优化network_config.xml配置

在网络配置中明确包含所有环回地址,覆盖IPv4和IPv6场景,同时保留模拟器常用地址:

<domain-config cleartextTrafficPermitted="true">
    <!-- 允许IPv4/IPv6环回地址 -->
    <domain includeSubdomains="true">127.0.0.1</domain>
    <domain includeSubdomains="true">::1</domain>
    <domain includeSubdomains="true">localhost</domain>
    <!-- 模拟器常用调试地址 -->
    <domain includeSubdomains="false">10.0.2.2</domain>
    <domain includeSubdomains="false">10.0.3.2</domain>
</domain-config>

同时确保测试用的AndroidManifest.xml中包含必要的网络权限:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

4. 测试前强制初始化localhost映射

在测试启动前,手动向/etc/hosts添加localhost到环回地址的映射,确保系统能正确解析:

@BeforeClass
fun setupLocalhostMapping() {
    val hostsFile = File("/etc/hosts")
    val hostsContent = hostsFile.readText()
    if (!hostsContent.contains("127.0.0.1 localhost") || !hostsContent.contains("::1 localhost")) {
        hostsFile.appendText("\n127.0.0.1 localhost\n::1 localhost")
    }
}

注意:该方法仅适用于模拟器或有root权限的测试设备,需确保测试进程具备写入/etc/hosts的权限。

内容的提问来源于stack exchange,提问作者AShX

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 07:54:52