当前位置: 首页 > news >正文

错误示例和如何规避


任务一:支持能力集,联想能力集与要求能力集解析

这三个“能力集”是理解和解决 HarmonyOS 跨设备兼容性问题的基石。它们共同决定了一个应用能开发什么功能能在哪些设备上运行

能力集 (Capability Set)中文名称角色与作用通俗比喻
Support Capability Set支持能力集设备方:定义了一台设备实际具备哪些系统能力。这是设备的“能力清单”,在设备出厂时就已确定。一台电脑的硬件配置单:有摄像头、有蓝牙、有指纹识别。
Required Capability Set要求能力集应用方:定义了你的应用运行所必需的最低能力。如果设备不满足这个列表,应用就不能被分发和安装游戏A的最低配置要求:必须有独立显卡、至少8GB内存。
Suggestion Capability Set联想能力集开发工具 (IDE):定义了你在 DevEco Studio 中写代码时能获得哪些 API 提示和联想。它通常是所有目标设备“支持能力集”的并集你买了一堆电脑配件(即使有些还不能用),工具书会把所有配件的用法都告诉你。
核心关系与规则:
  1. 安装规则:应用能否在设备上安装的唯一标准是:应用的“要求能力集”必须是设备“支持能力集”的子集

    • 示例:你的应用要求NFC.Core能力,那么它就无法安装在一台没有NFC芯片的手表上。
  2. 开发时的陷阱:“联想能力集”是为了方便开发,它会展示所有目标设备(如手机+手表)的能力总和。这意味着,你在手机项目中可能会看到并使用仅手表才有的API(比如心率传感器),反之亦然。这就导致了运行时兼容性风险

  3. 开发者要做的事

    • 谨慎定义“要求能力集”:只将应用绝对核心、不可或缺的能力放入。例如,一个支付应用可能强依赖NFC,就必须加入。
    • 动态判断非必要能力:对于那些“有则更好,无则隐藏”的功能(如心率监测、NFC读卡),不要放入“要求能力集”,而是在代码中进行运行时动态判断

任务二:系统能力相关 API 收集整理

在 ArkTS 中,进行运行时动态判断主要有两种官方推荐的方法。

1. canIUse():官方推荐的显式判断方法

这是最直接、最清晰的方法,用于检查当前设备是否支持某个具体的 SystemCapability (SysCap)。

  • API 签名: canIUse(syscap: string): boolean;
  • 参数: syscap - 一个表示系统能力的字符串,例如 'SystemCapability.Communication.NFC.Core'
  • 返回值: boolean - true 表示支持,false 表示不支持。
  • 优点: 意图明确,代码可读性高,是处理兼容性问题的首选方案。

整理示例

import hilog from '@ohos.hilog';// 检查NFC基础能力
if (canIUse('SystemCapability.Communication.NFC.Core')) {hilog.info(0x0000, 'SysCapCheck', '设备支持NFC基础能力');
} else {hilog.warn(0x0000, 'SysCapCheck', '设备不支持NFC基础能力');
}// 检查相机基础能力
if (canIUse('SystemCapability.Multimedia.Camera.Core')) {hilog.info(0x0000, 'SysCapCheck', '设备支持相机');
} else {hilog.warn(0x0000, 'SysCapCheck', '设备不支持相机');
}// 检查位置服务能力
if (canIUse('SystemCapability.Location.Location.Core')) {hilog.info(0x0000, 'SysCapCheck', '设备支持位置服务');
} else {hilog.warn(0x0000, 'SysCapCheck', '设备不支持位置服务');
}
2. import 模块判断 & try...catch 异常捕获

当一个设备不支持某个 SysCap 时,其对应的 API 模块在 import 时可能为 undefined,或者在调用时直接抛出错误。因此可以通过检查模块或捕获异常来判断。

  • 方法:
    1. import 模块后,在使用前判断其是否为 undefined
    2. 将 API 调用放在 try...catch 块中,如果设备不支持,调用会抛出一个错误(通常是 BusinessError,错误码 801 表示服务或能力不可用)。
  • 优点: 可以在调用失败时直接进入异常处理流程,适合处理那些调用本身就可能失败的复杂场景(如生物认证)。

整理示例

import nfcController from '@kit.ConnectivityKit'; // 假设新版SDK的导入方式
import userAuth from '@ohos.userIAM.userAuth';
import { BusinessError } from '@ohos.base';// 方式一:检查导入的模块
function checkNfcByImport() {if (nfcController) {console.info('NFC模块已成功导入,设备可能支持NFC。');// 进一步操作} else {console.error('NFC模块导入失败,设备不支持NFC。');}
}// 方式二:使用 try...catch 捕获异常
async function checkBiometrics() {const authParam: userAuth.AuthParam = {challenge: new Uint8Array([1, 2, 3, 4]),// 尝试使用人脸识别authType: [userAuth.UserAuthType.FACE],authTrustLevel: userAuth.AuthTrustLevel.ATL1,};try {const authInstance = userAuth.getUserAuthInstance(authParam, { title: '请验证' });await authInstance.start();console.info('人脸识别认证成功。');} catch (error) {const err = error as BusinessError;// 801 错误码通常表示能力不支持if (err.code === 801) {console.error('设备不支持人脸识别,错误信息: ' + err.message);// 在这里可以引导用户使用密码等其他方式} else {console.error('认证时发生其他错误: ' + JSON.stringify(err));}}
}

任务三:编写跨设备兼容性问题用例与纠错

以下是几个典型的跨设备问题用例,每个都包含“有问题的代码”和“纠错后的代码”。

用例 1:NFC 门禁卡模拟
  • 场景: 一个智慧社区应用,希望提供NFC模拟门禁卡功能。在有NFC的旗舰手机上运行良好,但在平板或没有NFC的手机上,点击“添加门卡”按钮时应用崩溃。
  • 相关 SysCap: SystemCapability.Communication.NFC.Core

有问题的 ArkTS 代码

// 错误示例:未做任何检查,直接调用NFC API
import nfcController from '@kit.ConnectivityKit';@Entry
@Component
struct Index {build() {Column() {Button('添加我的门卡').onClick(() => {// 在不支持NFC的设备上,nfcController为undefined,调用.isNfcAvailable()会直接导致应用崩溃const isNfcAvailable = nfcController.isNfcAvailable();console.log(`NFC可用状态: ${isNfcAvailable}`);// ...后续添加门卡的逻辑})}}
}

问题分析: 在没有NFC能力的设备上,nfcController 导入后是 undefined。执行 undefined.isNfcAvailable() 会立即抛出 TypeError,导致应用闪退。

纠错后的 ArkTS 代码

// 正确示例:使用 canIUse 进行前置判断
import nfcController from '@kit.ConnectivityKit';
import promptAction from '@ohos.promptAction';@Entry
@Component
struct Index {build() {Column() {Button('添加我的门卡').onClick(() => {// 步骤1:先用 canIUse 判断设备是否具备NFC能力if (canIUse('SystemCapability.Communication.NFC.Core')) {// 步骤2:在确保能力存在后,再安全地调用APIconst isNfcAvailable = nfcController.isNfcAvailable();if (isNfcAvailable) {promptAction.showToast({ message: '请将门卡贴近手机NFC区域' });// ...执行后续添加逻辑} else {promptAction.showToast({ message: '请在系统设置中开启NFC功能' });}} else {// 步骤3:在不具备能力的设备上,给出友好提示promptAction.showToast({ message: '抱歉,您的设备不支持NFC功能' });}})}.width('100%').height('100%').justifyContent(FlexAlign.Center)}
}
用例 2:地理位置打卡
  • 场景: 企业办公应用,需要员工到达公司后进行地理位置打卡。手机上正常,但在仅有WLAN的平板或智慧屏上,无法获取精确位置,可能导致应用逻辑异常或返回空数据。
  • 相关 SysCap: SystemCapability.Location.Location.Core, SystemCapability.Location.Location.Gnss

有问题的 ArkTS 代码:

// 错误示例:假设设备一定能获取到高精度位置
import geoLocationManager from '@ohos.geoLocationManager';@Entry
@Component
struct Index {async checkIn() {try {// 直接请求高精度位置,在室内或无GPS模块的设备上可能长时间无返回或失败const location = await geoLocationManager.getCurrentLocation();console.log(`打卡成功,位置: ${location.latitude}, ${location.longitude}`);} catch (err) {console.error('获取位置失败: ' + JSON.stringify(err));}}build() {Button('上班打卡').onClick(() => this.checkIn())}
}

问题分析: getCurrentLocation 在没有GPS模块(如仅WLAN的平板)或信号弱的设备上可能会超时或抛出异常。直接依赖其成功返回,会使应用在这些设备上打卡功能失效。

纠错后的 ArkTS 代码:

// 正确示例:检查能力并提供备选方案
import geoLocationManager from '@ohos.geoLocationManager';
import promptAction from '@ohos.promptAction';@Entry
@Component
struct Index {async checkIn() {// 判断1:设备是否支持位置服务if (!canIUse('SystemCapability.Location.Location.Core')) {promptAction.showToast({ message: '设备不支持定位功能' });return;}// 判断2:设备是否开启了位置服务if (!geoLocationManager.isLocationEnabled()) {promptAction.showToast({ message: '请在系统设置中开启位置服务' });return;}try {// 优先尝试获取缓存位置,速度快const lastLocation = await geoLocationManager.getLastLocation();if (lastLocation) {console.log(`通过缓存位置打卡成功: ${lastLocation.latitude}, ${lastLocation.longitude}`);return;}// 缓存没有再实时获取const location = await geoLocationManager.getCurrentLocation();console.log(`实时定位打卡成功: ${location.latitude}, ${location.longitude}`);} catch (err) {promptAction.showToast({ message: '获取位置失败,请稍后重试' });console.error('获取位置失败: ' + JSON.stringify(err));// 此处可以引导用户使用其他打卡方式,如连接公司WIFI打卡}}build() {Button('上班打卡').onClick(() => this.checkIn())}
}
http://www.dtcms.com/a/513091.html

相关文章:

  • 电子商务网站建设实训心得体会哪里做外贸网站
  • OPARTMENT发布Light 系列 以“光”重塑都市青年生活方式
  • Ubuntu 系统安装教程(二):系统安装
  • JVM调优实战:一次GC风暴的排查与优化全记录
  • 修改查询默认1W限制
  • 网站建设 宣传商丘网站建设有哪些
  • 商业网站的创建程序线上运营推广是做什么的
  • 泉港区建设局网站廉政网站建设调查的问卷
  • 常宁市城市建设规划管理局网站4a广告公司排名
  • CHI-Read Transaction
  • LeetCode——二分(进阶)
  • 便宜购 网站建设鹤岗商城网站建设
  • Vue图片压缩方案
  • python去掉不是ts文件的链接
  • 性病医院网站优化服务商中国品牌网站设计
  • win2008网站404成都职业培训网络学院
  • 网站源码授权wordpress调用相关页面
  • Excel 宏安全设置与强制启用宏
  • 万柳网站建设html网站开发中的应用
  • 中国站长小程序源码能直接用吗
  • 《通信之道—从微积分到5G》阅读笔记
  • 郑州网站建设网页设计网站备案转入
  • 广州网站建设出售sae wordpress 主题
  • 为什么在大数据处理场景下,存储过程比编程语言更合适?
  • 电子商务网站建设与管理课件辽宁建设工程信息网备案
  • 【软件安装】在 Visual Studio 2022 中安装 RDLC 报表插件的详细教程
  • Cloud Studio 免环境搭建创建机器学习环境并运行 Pytorch 案例
  • 11、【Ubuntu】【VSCode】VSCode 断联问题分析:getent 命令(一)
  • 网站被降权会发生什么影响吗怀化汽车网站
  • 护照阅读器识别行驶证:汽车检测站的效率助力