Android 16 下 uni-app APP 提示“网络连接失败”的排障与修复

Android 16 下 uni-app APP 提示"网络连接失败"的排障与修复

一次看起来很普通的网络故障,最后却和服务器、联网权限、HTTP 明文访问都没有关系。

在这次问题中,手机浏览器可以正常访问后端健康检查接口,并得到:

json 复制代码
{
  "status": "UP",
  "groups": ["liveness", "readiness"]
}

H5 页面也能正常使用,但同一套前端代码打包为 APK、安装到手机后,请求验证码时却始终提示"网络连接失败"。

查看打包的APP的应用设置,发现也有流量数据,于是外卖需要考虑到的就不是没有打开APP的联网功能。

这个现象很容易让人继续排查服务器、防火墙、反向代理和 Android 联网权限,实际故障发生得更早:APK 内的旧版 DCloud 原生网络适配器在创建请求时就已经抛出异常,请求根本没有发到服务器。

本文记录完整的定位过程、真实原因和修复方法,供后续遇到类似问题时快速复用。

一、问题现象

当时的环境组合如下:

项目 问题环境
手机系统 Android 16(API 36)
APK targetSdkVersion 36
本机 HBuilderX 4.29,发布于 2024 年
@dcloudio/uni-* 依赖 3.0.0-4020420240722001
后端状态 已部署,健康检查正常
H5 状态 可以正常访问后端
APK 状态 验证码请求提示"网络连接失败"

前端的统一请求封装会把底层网络异常转换成便于用户理解的提示,因此页面上只显示"网络连接失败"。这个提示描述的是最终表现,并不等于故障一定发生在网络连接阶段。

二、为什么最初的排查方向不对

1. 不是 Android 联网权限缺失

项目的 talk-ui/src/manifest.json 已声明:

xml 复制代码
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

因此不是忘记声明 INTERNET 权限。

2. 不是 HTTP 明文访问被系统禁止

项目在 Android 配置中保留了:

json 复制代码
{
  "usesCleartextTraffic": true
}

这仍然是当前 HTTP 内测环境需要的配置,但它不是本次故障的原因。日志显示异常发生在 DCloud 网络适配器初始化 TLS 协议时,此时业务请求还没有被创建,更没有进入 HTTP 明文访问检查阶段。

3. 后端健康检查正常不代表 APK 请求栈正常

手机浏览器访问健康检查成功,只能证明下面这条链路可用:

text 复制代码
手机网络 -> 浏览器网络栈 -> 公网入口 -> 后端服务

APK 发起请求时走的是另一条链路:

text 复制代码
uni-app 页面 -> DCloud 原生网络适配器 -> Android 网络栈 -> 公网入口 -> 后端服务

两条链路共用同一个服务器,却不共用同一个客户端网络实现。H5 正常而 APP 异常时,不能只盯着后端,还要检查原生运行时和打包基座。

三、用 ADB 找到真正的异常

连接开启 USB 调试的手机后,先确认设备和 Android API 级别:

powershell 复制代码
adb devices -l
adb shell getprop ro.build.version.release
adb shell getprop ro.build.version.sdk

再确认已安装 APK 的目标 SDK:

powershell 复制代码
adb shell dumpsys package com.seekta.mobile |
  Select-String "targetSdk"

复现前清空日志,然后在手机上重新点击获取验证码:

powershell 复制代码
adb logcat -c
adb logcat |
  Select-String "IllegalArgumentException|TLSv1|com.seekta.mobile"

最终捕获到的核心异常是:

text 复制代码
java.lang.IllegalArgumentException: protocol TLSv1 is not supported

这条日志给出了两个关键信号:

  1. 异常发生在客户端创建请求之前,而不是服务器返回错误之后。
  2. 失败对象是 APK 内的原生网络层,不是 Vue 页面中的业务接口代码。

与此同时,服务器访问日志中没有对应的验证码请求。客户端异常和服务器无请求记录互相印证,说明请求确实没有离开手机。

四、真实原因:新系统运行了旧版原生网络适配器

旧 APK 的兼容链条是:

text 复制代码
Android 16 / API 36
        +
targetSdkVersion 36
        +
HBuilderX 4.29 的旧版 App 原生运行时
        +
2024 年 7 月版本的 @dcloudio/uni-* 编译依赖
        ↓
旧网络适配器尝试启用 TLSv1
        ↓
Android 运行环境拒绝该协议配置
        ↓
请求创建失败,前端显示"网络连接失败"

问题并不是服务器要求使用 TLSv1。实际情况是旧版 DCloud 网络适配器在初始化网络客户端时仍带有旧协议配置,而该配置在 Android 16、targetSdkVersion 36 的运行组合下不再被接受。

这也解释了为什么修改 API 地址、重复检查服务器、增加联网权限都没有效果:这些配置位于请求链条的后半段,而程序在原生网络客户端初始化阶段就已经失败了。

五、修复方案

修复的核心不是绕过 Android 的安全限制,也不是重新开启 TLSv1,而是升级 DCloud 工具链和 uni-app 依赖,让新 APK 使用与 Android 16 兼容的原生网络实现。

第一步:升级 HBuilderX

将用于发行 APK 的 HBuilderX 升级到 5.24。打包电脑上真正执行"原生 App 云打包"的 HBuilderX 版本尤其重要,因为最终 APK 的原生基座由打包环境决定。

DCloud 的云打包环境文档显示,HBuilderX 5.09 及以上版本已经采用面向 API 36 的新版 Android 编译环境,因此继续使用 2024 年的旧工具链并不适合验证 Android 16 兼容性。

升级后重新打开项目,不要继续使用旧 HBuilderX 生成的 APK 做验证。

第二步:统一升级 uni-app 依赖

提交 c2df5b61b0dd6ebd43c51fb9bd2e85fe706486d2 完成了这一步,提交信息为:

text 复制代码
build(app): 升级 uni-app 依赖至 HBuilderX 5.24

该提交把 talk-ui/package.json 中 9 个 DCloud 依赖统一从:

text 复制代码
3.0.0-4020420240722001

升级为:

text 复制代码
3.0.0-5020420260812001

涉及的依赖包括:

text 复制代码
@dcloudio/uni-app
@dcloudio/uni-app-plus
@dcloudio/uni-components
@dcloudio/uni-h5
@dcloudio/uni-mp-weixin
@dcloudio/uni-automator
@dcloudio/uni-cli-shared
@dcloudio/uni-stacktracey
@dcloudio/vite-plugin-uni

DCloud 相关包必须使用同一发行版本,不应只升级其中一两个包,否则编译器、运行时和插件之间可能产生新的版本不一致。

第三步:重新安装依赖并确认版本

进入前端项目目录:

powershell 复制代码
Set-Location .\talk-ui
npm install

当前项目忽略了 package-lock.json,本地可能还残留旧锁文件,因此不要只根据锁文件判断实际版本。安装完成后直接检查已安装依赖:

powershell 复制代码
npm ls `
  @dcloudio/uni-app `
  @dcloudio/uni-app-plus `
  @dcloudio/vite-plugin-uni

输出中的 DCloud 版本应与 talk-ui/package.json 保持一致,不应继续出现 4020420240722001

第四步:完成 APP 资源构建检查

powershell 复制代码
npm run build:app

看到 DONE Build complete 说明前端 APP 资源编译通过。需要注意,这一步只生成待打包资源,并不会自动替换手机里 APK 的原生网络层。

第五步:使用 HBuilderX 5.24 重新云打包

在 HBuilderX 5.24 中重新执行:

text 复制代码
发行 -> 原生 App-云打包 -> Android

打包时继续使用项目原有的以下身份配置:

  • DCloud AppID;
  • Android 包名;
  • DCloud 云端证书或原有签名证书。

不要为了修复网络问题更换包名或签名证书,否则新 APK 可能无法覆盖安装旧版本。分发前还应递增 talk-ui/src/manifest.json 中的 versionCode

真正包含新版原生网络适配器的是重新云打包生成的 APK。仅更新 H5、仅运行 npm run build:app,或者继续安装旧 APK,都无法验证这次原生层修复。

第六步:覆盖安装并复验

回到仓库根目录,使用新 APK 覆盖安装旧版本:

powershell 复制代码
adb install -r .\talk-ui\dist\release\apk\新版本.apk

覆盖安装可以同时验证签名一致性和升级路径,也能保留原有本地数据。安装后重新打开 APP,依次检查:

  • 登录页可以加载验证码;
  • 刷新验证码可以正常发起新请求;
  • 登录、注册及其他 API 可以访问;
  • ADB 日志中不再出现 protocol TLSv1 is not supported
  • 后端访问日志可以看到来自 APP 的实际请求。

六、修复后的验证闭环

一次完整验证不能只看"页面不再报错",建议同时检查四层证据:

验证层级 通过标准
前端页面 验证码正常展示,不再提示网络连接失败
Android 日志 不再出现 TLSv1 协议初始化异常
服务端日志 可以看到验证码接口请求到达服务器
构建版本 APK 来自 HBuilderX 5.24,DCloud 依赖为 5020420260812001

只有这四层同时成立,才能确认手机中运行的确实是修复后的新 APK,而不是浏览器缓存、H5 资源或旧安装包造成的假象。

需要说明的是,DCloud 官方资料用于确认打包环境、目标 SDK 和版本兼容配置;protocol TLSv1 is not supported 的具体根因判断来自本次 ADB 日志、服务器无请求记录以及升级后真机恢复正常这三项证据,并非引用自 DCloud 的故障公告。

七、以后遇到"APP 网络不可用"应该怎么查

这次问题最值得保留的不是某一条命令,而是排查顺序。

先判断请求有没有离开客户端

同时观察 ADB 日志和服务器访问日志。如果服务器完全收不到请求,就优先检查客户端原生层、DNS、证书、协议初始化和系统兼容性,不要急着修改后端业务代码。

对比 H5 与 APP 的差异

同一接口出现"H5 正常、APP 失败"时,重点检查:

  • HBuilderX 和 @dcloudio/uni-* 是否来自同一代版本;
  • APP 是否使用了过旧的原生运行时或自定义基座;
  • Android 系统版本和 targetSdkVersion 是否刚刚升级;
  • APK 是否确实重新云打包,而不是只更新了前端资源;
  • 原生插件是否兼容当前云打包环境。

不要被统一错误文案限制思路

"网络连接失败"通常只是前端的兜底提示。排障时必须找到底层原始异常,尤其要关注:

text 复制代码
IllegalArgumentException
SSLHandshakeException
UnknownHostException
ConnectException
Cleartext HTTP traffic not permitted

这些异常分别指向协议初始化、TLS 握手、DNS、连接建立和 HTTP 明文策略,处理方式完全不同。

八、结论

这次故障的最终结论可以概括为一句话:

Android 16 与 targetSdkVersion 36 暴露了旧版 DCloud 原生网络适配器的 TLSv1 配置问题,导致请求在创建阶段失败;升级 HBuilderX 和整套 @dcloudio/uni-* 依赖,并重新云打包 APK 后恢复正常。

后端健康检查成功并没有错,Android 权限和 HTTP 明文配置也没有错。真正缺失的是"前端源码、uni-app 编译依赖、HBuilderX 打包环境、APK 原生基座、目标 Android 系统"这一整条版本兼容链的检查。

跨端项目中的"同一套代码"并不代表"同一套运行时"。遇到只有 APP 出现的网络问题时,原生基座版本应该和服务器地址一样,成为第一批核对项。

参考资料

相关推荐
2501_915106322 小时前
苹果App Store上架费用及流程全面解析
android·ios·小程序·https·uni-app·iphone·webview
YF02114 小时前
Android 16系统App开机自启动方案
android
hm宋5 小时前
安卓手机卡顿优化 —— 背景与使用指南
android
OxYGC5 小时前
[Android] [WatchOS]智能手表第一篇: 实用工具与应用推荐
android·智能手表
白远山6 小时前
家政服务派单平台搭建实战指南:从需求分析到系统设计全流程解析
java·开发语言·架构·uni-app·需求分析
嘟哩DuliDuli7 小时前
创作 Agent 的任务状态该如何保存
android·java·javascript
Godikov8 小时前
两个 SDK 抢一个摄像头:Android 设备上的相机仲裁设计与踩坑实录
android
Godikov8 小时前
摄像头电机自动校准实战:为什么我用「步数计数」替换了角度传感器绝对定位
android