多设备兼容性与版本管理

一、引言

breakpoint-system 多设备应用最大的技术债务不在 UI,而在"同一套代码跑在能力悬殊的六类设备上"。HarmonyOS 通过 compatibleSdkVersion/targetSdkVersion 双版本机制约束 API 面,通过模块 deviceTypes 约束安装目标,但真正的兼容性风险来自运行时差异:屏幕尺寸、交互方式、系统版本、性能水位。一个典型的翻车现场是:手机端验证通过的版本,在旧系统平板上首帧白屏、在手表上内存溢出、在智慧屏上焦点丢失。本文结合本工程的构建配置与 README 约束,给出多设备兼容性的判定方法、降级策略与版本管理规范。

二、系统与 SDK 版本约束

版本约束是兼容性的第一道闸门。本工程在根 build-profile.json5 中声明了产品级版本:

// d:\HarmonyOS\WorkSpace\multi-short-video\build-profile.json5
{
  "app": {
    "products": [
      {
        "name": "default",
        "signingConfig": "default",
        "targetSdkVersion": "6.1.0(23)",
        "compatibleSdkVersion": "6.1.0(23)",
        "runtimeOS": "HarmonyOS"
      }
    ]
  }
}

两个版本字段含义不同:compatibleSdkVersion 是应用可运行的最低 API 版本,向下兼容的下限,系统版本低于它的设备不允许安装;targetSdkVersion 是应用编译与测试的目标 API 版本,系统据此决定是否启用新行为——同一段代码在 targetSdkVersion 不同时,可能触发不同的系统策略(如后台限制、权限行为)。本工程两者同为 6.1.0(23),即要求设备系统不低于 API 23 才能安装,这比 README.md 中"HarmonyOS 5.0.5 Release 及以上"的运行约束更严格,属于示例工程的保守做法。生产项目通常会让 compatibleSdkVersion 适当低于 targetSdkVersion,扩大可安装设备的范围,代价是必须为低版本 API 做条件适配。

工程层面的版本链必须整体对齐,对照 README 的约束与限制,可用下表盘点:

维度README 约束本工程实际

系统版本HarmonyOS 5.0.5 Release 及以上根 build-profile 6.1.0(23) 编译
开发工具DevEco Studio 6.0.2 Release 及以上工程 modelVersion 6.1.0
SDKHarmonyOS 6.0.2 Release SDK 及以上target/compatible 6.1.0(23)
支持设备手表、直板机、折叠屏、平板、电脑、智慧屏deviceTypes 分四组声明

这里的"约束"不是 README 写给自己看的装饰,而是对外承诺的能力边界:用户在低版本设备上安装失败时,README 与商店说明就是第一解释文档;开发者升级 SDK 时,版本约束表就是回归范围的依据。建议把这张表同步维护到 README 与上架资料中,保持"文档承诺 = 工程配置"。

在工程实践中,建议在 CI 里增加一条"版本约束校验"任务:解析根 build-profile.json5 的 compatibleSdkVersion/targetSdkVersion 与 README 中声明的约束做一致性比对,任何一边改动而另一边未同步时构建失败。这样"文档承诺 = 工程配置"就从口头约定变成了可执行的自动化检查,避免出现"README 写着 5.0.5 兼容、实际包已要求 6.1.0"的乌龙。

三、设备能力差异与安装目标隔离

不同设备的差异远不止分辨率,还涉及交互方式、内存水位、播放能力。本工程用模块级 deviceTypes 把设备分组,四类产品各管一段:

// products/pc/src/main/module.json5(节选)
"deviceTypes": [ "2in1" ]

// products/tv/src/main/module.json5(节选)
"deviceTypes": [ "tv" ]

// products/wearable/src/main/module.json5(节选)
"deviceTypes": [ "wearable" ]

// products/default/src/main/module.json5(节选)
"deviceTypes": [ "phone", "tablet" ]

由此形成能力矩阵:

设备组屏幕交互视频播放评论个人页

phone/tablet竖屏优先触摸全屏沉浸半模态新页/分栏
2in1横屏自由缩放鼠标键盘分栏播放侧面板分栏
tv远距离大屏遥控器焦点横向焦点侧面板分栏
wearable极小屏旋钮/触摸精简裁剪裁剪

这正好解释了为什么四类产品的 module.json5 在 abilities、extensionAbilities(备份扩展)、routerMap 上各有取舍:能力差异不是 UI 问题,而是功能裁剪问题——手表端干脆不引入评论模块,由 features/multishortvideocomment 不参与引用实现。deviceTypes 决定了 HAP 的安装目标,但要注意:同一模块的 deviceTypes 列表内多类设备共享同一份产物(如 default 同时覆盖 phone 与 tablet),此时差异必须靠断点等运行时手段消化,这正是第六章断点系统的用武之地。

除安装目标外,deviceTypes 还影响系统对 HAP 的展示与审核策略:智慧屏设备对应用的上架审核有独立要求(如遥控器可操作性、焦点可见性),穿戴设备对包体大小与应用功耗有更高要求。因此产品划分不能只看"现在有哪些设备",还要考虑"每种设备形态的审核与分发成本"——把交互差异大的形态拆成独立 product,把交互相近的形态合并进同一 product(如 phone 与 tablet),是兼顾工程量与合规成本的最优解。本工程的划分(default 覆盖手机平板、pc 独立、tv 独立、wearable 独立)正是这一原则的体现。

四、API 兼容性判断与降级策略

多设备上最容易翻车的是"新 API 在老设备上崩溃"。判断 API 可用性有四种手段:

  • canIUse:运行时查询接口/组件是否支持,适合轻量判断;
  • 系统版本判断:通过 deviceInfo@ohos.deviceInfo 获取 major/minor 版本,与常量比较后分支处理;
  • try/catch 兜底:对可选能力(如新的手势 API、新的窗口属性)做异常降级;
  • 编译期条件:用 SDK 条件编译区分不同 API 面,避免低版本打包进新接口。

四种手段的选型原则是:能用 canIUse 就不做版本判断,能用版本判断就不靠 try/catch,编译期条件只用于"该 API 在当前 SDK 不存在"的情况。降级策略的关键是默认路径要落在低能力一侧:新能力是"增强",旧能力是"保底",而不是反过来。

以"大屏设备是否启用分栏评论"为例,降级链路可以这样组织:

// 伪代码示意:能力探测 → 版本分支 → 异常兜底
const SUPPORT_SPLIT = 0x06; // 假设分栏能力自某系统版本起支持
const splitSupported = canIUse('SystemCapability.ArkUI.Advanced.Split') ||
  (deviceInfo.majorVersion >= 5 && deviceInfo.minorVersion >= 1);
try {
  // 启用分栏评论;不支持时回退到全屏半模态
  enableSplitComment(splitSupported);
} catch (e) {
  enableSplitComment(false); // 异常兜底,绝不崩溃
}

这套代码的核心是"三层递进":canIUse 快速探测 → 版本判断补漏 → try/catch 兜底,三层只要有一层判定不支持,就走低能力路径。注意 enableSplitComment(false) 本身不能再抛异常,兜底路径必须是纯 UI 逻辑的保守实现。

本工程一个典型的降级范式是断点驱动的布局切换:common/multishortvideobase/src/main/ets/utils/WidthBreakpointType.ets 通过 onWindowSizeChange 动态维护断点,手机竖屏走全屏列表、平板展开态走分栏,能力差异被收敛到"断点 → 形态"的映射里,而不是散落各处的 if 判断。这给兼容性设计一个启示:把设备差异抽象成业务可理解的维度(断点、能力标记),比逐 API 判断更容易维护。同理,TV 端的焦点系统(TvTabs.ets 的 focusable/focusOnTouch)与 PC 端的鼠标事件(products/pc/.../Index.ets)也在产品层各管一段,把"交互方式差异"隔离在入口模块内,features 层业务无需感知。

五、工程级版本管理与回归

版本管理要覆盖工具链、依赖与产物三层:

  • 工具链版本hvigor/hvigor-config.json5 与根 oh-package.json5modelVersion: 6.1.0 定义了 hvigor 构建模型版本,升级 DevEco Studio 后可能触发构建脚本变更,需在团队内统一并回归构建。
  • 依赖版本:根 oh-package.json5 的 devDependencies 声明了 @ohos/hypium: 1.0.25@ohos/hamock: 1.0.0,这些测试框架版本与 SDK 强相关,升级 SDK 时必须回归单测。
  • 产物版本:四个 HAP 的 versionCode 必须同步递增(见第 56、57 篇),签名证书保持一致,避免"手机端升了、平板端没升"导致跨设备数据异常。
工程级的版本锁定建议写入 hvigor/hvigor-config.json5 的 execution 配置(daemon、incremental、parallel 等开关影响构建行为),并配合 CI 在统一镜像中构建,从源头消除"本机能跑、CI 构建失败"的工程事故。

上架前的多设备回归清单:直板机(竖屏滑流、半模态评论)、平板(分栏切换、栅格作品页)、折叠屏(展开/折叠断点跳变)、电脑(窗口缩放、鼠标悬停、SideBarContainer 折叠)、智慧屏(焦点导航、遥控器键控)、手表(精简页签、旋钮滚动)。每类设备至少覆盖"首帧渲染、视频播放、评论交互、个人页跳转"四条主链路,且必须用最低支持版本系统的真机跑一遍,因为模拟器无法复现真实性能与窗口行为。折叠屏与三折叠设备尤其要测展开/折叠过程中的 onWindowSizeChange 触发与断点切换,这是多设备应用最高频的崩溃来源之一。

回归结果建议按矩阵登记,逐格打勾,任何一格为"未测"都视为发布阻塞项:

设备首帧视频播放评论个人页断点切换最低系统

直板机必测必测半模态新页跳转横竖屏5.0.5
折叠屏必测必测双形态分栏展开/折叠5.0.5
平板必测必测分栏分栏旋转5.0.5
电脑必测必测侧面板侧面板窗口缩放5.0.5
智慧屏必测必测侧面板焦点导航5.0.5
手表必测精简版裁剪裁剪5.0.5

这张矩阵同时是版本发布前的"放行凭据":只有六行全绿,才允许进入 AGC 提审流程。

六、总结与最佳实践

多设备兼容性的本质是"用版本约束圈住边界,用能力抽象消化差异"。本工程给出的范式值得复用:

  • 双版本约束:compatibleSdkVersion 定下限、targetSdkVersion 定目标,二者随 SDK 演进同步维护,并在 README 中明确对外约束(HarmonyOS 5.0.5+、DevEco 6.0.2+),文档承诺与工程配置保持一致。
  • deviceTypes 分组隔离:按交互形态而非屏幕尺寸分组,phone/tablet、2in1、tv、wearable 四类产物各归其位,能力差异在模块边界消化。
  • API 降级成体系:canIUse、版本判断、try/catch 三层递进,配合"断点 → 形态"的抽象让差异可控,默认路径落在低能力一侧。
  • 版本管理进 CI:工具链、依赖、HAP 产物三级版本统一校验,杜绝"本机能跑、CI 构建失败"的工程事故。
  • 回归以最低版本真机为准:把上架前多设备回归清单脚本化,宁可多测一台老设备,不赌一个未覆盖的 API。

兼容性管理没有银弹,它的本质是"已知的边界 + 可控的回归"。边界写进配置与文档,回归写进清单与 CI,多设备这座山就能一步步爬过去。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐