
做产品的人对“升级”通常有一种直觉:版本号往上跳一跳,功能别坏,就差不多了。但 HarmonyOS 7(API 26)的升级不是一次普通的版本迭代,它更像一次变更管理——你改动的不是一个数字,而是系统对待你应用的方式、依赖链的兼容性,以及发布流程里那些平时不会显形的环节。
我见过一种很典型的场景:开发同学把配置改完,编译通过,模拟器上跑了一圈,说“没问题了”。提交审核,驳回。回头一查,问题不在新写的代码里,而在一个三方依赖的旧接口上,或者一个权限的触发时机和审核预期对不上。编译通过只代表代码能编,不代表升级完成。这篇文章从产品视角把这件事拆开,适合你在排期、验收和上架准备时直接对照。
三个“版本号”,别混成一个
HarmonyOS 工程的 build-profile.json5 里有三个容易混淆的配置项,产品经理不需要会写代码,但必须理解它们各自管什么,否则排期和验收都会错位。
compileSdkVersion 决定编译时能用哪些 API,它只影响构建阶段。targetSdkVersion 决定系统在运行时按哪个版本的行为对待你的应用——这是最容易被低估的一个。compatibleSdkVersion 决定你的应用最低能装在什么系统版本的设备上。三者有一个硬约束:compileSdkVersion >= targetSdkVersion >= compatibleSdkVersion。
升级到 API 26 时,核心动作通常是把 targetSdkVersion 改为 "26.0.0",而 compatibleSdkVersion 一般保持不动,不因为升级而随意抬高旧设备的门槛。配置示例如下,可以直接对照你的工程:
{
"compileSdkVersion": "6.0.0(20)",
"targetSdkVersion": "6.0.0(20)",
"compatibleSdkVersion": "5.0.0(12)"
}
{
"compileSdkVersion": "26.0.0",
"targetSdkVersion": "26.0.0",
"compatibleSdkVersion": "5.0.0(12)"
}
一个常见的误操作是:只改了 compileSdkVersion,targetSdkVersion 没动。这会让系统仍然按旧版本的行为对待你的应用,看起来一切正常,但实际上新版本的行为你根本没有测到。产品经理在验收时可以直接问一句:“targetSdkVersion 真的升到 26 了吗?”——这个问题能筛掉相当一部分“假升级”。
编译过了,为什么跑起来还是不对
这是 API 升级里最隐蔽的一类问题:接口名没变,参数没变,但系统行为变了。编译完全正常,运行时才暴露。
比如 TreeSet / TreeMap 在扩容时比较器丢失的问题,官方变更明确做了版本隔离,只有在 targetSdkVersion >= 6.0.0(20) 时才生效。也就是说,你的应用一旦把目标版本提上去,同一个接口在旧版本上跑得好好的逻辑,在新目标版本下可能产生错误结果。再比如公共事件的订阅范围,某些 COMMON_EVENT_PACKAGE_* 事件在三方应用中的监听权限被收紧了,变更前系统应用和三方应用都能监听,变更后三方应用只能监听到自身应用的相关事件。如果产品里有“检测其他应用安装状态”之类的功能,升级后可能直接失效,而编译阶段不会有任何报错。
还有一个容易被忽略的层面:三方 HAR 依赖。你项目里引用的某个库,编译时用的是旧 API,升级到 API 26 之后,它在新系统上的运行时行为可能出问题。这类问题靠“启动一下看看”是发现不了的,必须扫描依赖链,确认每个关键三方库的兼容状态。
DevEco Studio 里有一个 API Change Assistant 工具,可以扫描项目代码,列出哪些接口被废弃、哪些行为发生了变化、哪些新增接口需要适配。产品经理不一定亲自操作,但应该在升级排期里明确要求团队跑一遍这个扫描,并把报告作为验收材料之一——它比“开发说没问题”可靠得多。
兼容旧设备,不是“最低版本写低一点”就完了
compatibleSdkVersion 保持不变,意味着你的应用仍然要分发到旧系统设备上。但你的代码已经按照新目标版本的行为写了,这就产生了一个需要显式处理的矛盾:同一段逻辑,在新设备上走新行为,在旧设备上必须回退到旧行为。
官方给出的做法是在代码里做版本判断,而不是一刀切。以 HarmonyOS 专有接口为例,可以用 distributionOSApiVersion 来判断设备实际支持的版本,再决定走哪条逻辑分支:
import { deviceInfo } from '@kit.BasicServicesKit';
if (deviceInfo.distributionOSApiVersion >= 50002) {
} else {
}
如果是 OpenHarmony 底座接口,则使用 sdkApiVersion 做类似判断。产品经理不需要记住这些常量,但需要理解一件事:兼容旧设备不是把最低版本填低就自动实现的,它需要在关键路径上有显式的版本分支,并且这些分支都要进回归范围。排期时如果只预留了“升级配置”的时间,没有预留“兼容分支开发和旧设备验证”的时间,上架前一定会在这里卡住。
上架排障:先拆问题,再动手改
审核驳回在产品视角下往往被当成“运气问题”,但在 API 26 升级的语境里,驳回原因通常可以归到几类可排查的方向。
比较常见的驳回逻辑是权限与使用场景不匹配。比如应用申请了系统级后台保活的高级权限,但实际业务用普通级别的后台权限就能满足,审核会要求遵循权限最小化原则,并在 module.json5 的 requestPermissions 中明确声明使用场景。隐私合规层面的高频问题还包括:在用户同意隐私政策之前就获取个人信息或权限、隐私政策没有以明示同意的方式征得用户同意(默认勾选或登录即同意都不行)、权限清单没有覆盖所有 hap / hsp / har 模块。
产品经理在收到驳回时,一个有效的动作是先把问题分类,再分配整改:是合规问题、功能完整性问题、稳定性问题,还是提交材料不一致。不要为了“赶紧过审”一次性大改权限、文案和功能——即使问题消失了,你也无法确认真正的原因,下一轮可能以另一种形式回来。每个整改项都应该带三样东西:复现步骤、具体修改点、回归结果。这套证据链在后续版本迭代和灰度决策中都会反复用到。
把升级当成一次可回滚的变更,而不是一次“修到过”的冲刺
一个实用的推进顺序是这样的:先从主干拉出升级分支,记录升级前的配置和可复现的构建结果;再逐项改动,这样任何异常都能明确归因到工具链、目标版本还是依赖变化。验证分三层走——工程层确认干净环境下依赖同步、构建、签名和打包都能复现;行为层在 HarmonyOS 7 目标设备和声明支持的旧版本上分别跑关键流程(登录、支付、推送、相机、文件访问、后台任务,按产品实际能力覆盖);发布层复核包名、版本号、签名、资源、渠道配置和测试记录。
升级计划里需要有负责人、影响面、灰度策略和回滚条件。如果升级涉及核心行为,保留上一稳定版本和服务端开关,避免客户端发布后发现问题只能被动等待商店更新。一个简单的应用,动作可能只是升级工具链、改版本配置、跑新老系统回归;复杂应用还要加上三方库扫描、行为变更逐项确认和端到端业务验证。规模不同,但底层逻辑一样:把变更拆小,把证据留全,把回退方案准备好。
给产品经理的 API 26 升级检查清单
targetSdkVersion 已显式改为 "26.0.0",不只是改了 compileSdkVersion
compatibleSdkVersion 未被随意抬高,旧设备分发范围符合产品预期
- API Change Assistant 已运行,行为变更和废弃接口有明确处理结论
- 关键三方 HAR / SDK 已确认兼容 API 26,或有替代方案
- 新旧系统设备上均完成关键流程回归,不只是启动测试
- 权限清单(所有 hap / hsp / har 模块)与
requestPermissions 使用场景一致
- 隐私政策弹窗非默认勾选、非登录即同意,个人信息获取发生在同意之后
- 包名、版本号、签名、渠道配置与提交材料一致
- 灰度策略和回滚条件已写入升级计划,上一稳定版本可回退
升级和上架不是最后一天的手续。把它当成一次普通的工程变更来管理——有分支、有验证、有证据、有退路——通常比临近截止日期时集中“修到过”更省时间,也更少意外。
本文由 @彭可 授权发布于人人都是产品经理。未经作者许可,禁止转载
题图来自Unsplash,基于CC0协议
该文观点仅代表作者本人,人人都是产品经理平台仅提供信息存储空间服务