Flutter使用new_version包实现版本更新失效报错问题咨询
故障根因
该故障确实由Google Play Store侧的页面结构变动导致,和你的业务代码逻辑无关:
- 你使用的
new_version包在Android端的版本号获取逻辑,是通过爬取Play Store应用公开详情页的DOM节点,匹配对应元素提取商店版本号。 - 2022年年中Google Play灰度调整了应用详情页的渲染规则:当检测到用户本地安装版本低于商店最新版时,页面会走更新提示分支的渲染逻辑,版本号所在的DOM节点结构、位置和包内置的匹配规则不匹配,包内调用
List.firstWhere查找节点时没有设置兜底逻辑,找不到匹配元素就直接抛出Bad state: No element未捕获异常。 - 你观察到的「仅安装最新版本时功能正常」现象刚好和这个变动匹配:用户安装最新版时,页面展示「已安装最新版本」的固定提示块,该块的DOM结构还符合旧版匹配规则,因此不会触发报错。
修复方案
紧急止血处理
先给现有版本检查逻辑加异常捕获和空判断,避免功能崩溃,不要对getVersionStatus的返回值直接做!强制非空,修改后的参考代码如下:
void _checkVersion() async { try { final newVersion = NewVersion( androidId: "com.abc.def", ); final status = await newVersion.getVersionStatus(); // 组件未挂载、或版本信息获取失败时直接返回,不执行后续弹框逻辑 if (!mounted || status == null) return; newVersion.showUpdateDialog( context: context, versionStatus: status, dialogTitle: "UPDATE!!!", dialogText: "Please update the app from ${status.localVersion} to ${status.storeVersion}", updateButtonText: "Lets update", ); } catch (e) { // 版本检查失败时静默处理即可,可按需加日志埋点 debugPrint("应用更新检查失败: $e"); } }
彻底修复方案
- 如果你要继续使用
new_version包,可以修改本地依赖中new_version.dart文件内的_getAndroidStoreVersion方法:给所有调用firstWhere查找DOM节点的逻辑增加orElse兜底参数,找不到节点时返回null而非直接抛异常,同时兼容Play Store新旧两种页面结构的版本号节点匹配规则。 - 长期维护建议替换为Google官方提供的应用内更新API实现更新提示,官方接口不存在页面结构爬取失效的问题,稳定性远高于第三方爬取实现。
补充说明
你提到的「此前功能正常、升级包到最新版本仍未解决」属于灰度推送的正常现象:Google Play的页面结构调整是分地区、分账号逐步放量的,不同用户触达变更的时间存在差异,因此会出现功能无改动突然失效的情况;2022年7月这次调整刚推送时,new_version包的最新版本也未及时完成全场景适配,因此升级包无法直接解决问题。
内容的提问来源于stack exchange,提问作者Gimuser39
相关产品推荐
相关产品推荐

