OpenHarmony开发者论坛

标题: OpenHarmony_SDK与系统能力详解 [打印本页]

作者: Laval社区小助手    时间: 2023-12-26 15:24
标题: OpenHarmony_SDK与系统能力详解
[md]## 详情:[OpenHarmony_SDK与系统能力详解](https://laval.csdn.net/6480214e6bf8dd0412f5006f.html)

## SDK子系统

**SDK子系统基于一套OpenHarmony源码,生成归一化的SDK可满足多设备的应用开发。**

**面向多设备,多系统,多应用只提供一套 SDK,具体可分解为三个维度:**

1. **多端开发特性归一化** **针对能力不同设备,只提供一个 OH SDK,不单独提供针对某个设备的 SDK,不存在手机SDK,手表SDK。**
2. **兼容性归一化** **只提供 OH 的 SDK,HOS 不单独提供 SDK,HOS 独有的竞争力特性以 addon 的方式提供给开发者。**
3. **多应用支持归一化** **SDK 中包含三方 API 和系统 API,不单独提供系统 SDK 给系统应用。 **

**SDK在提供编译工具链、开发工具、运行时的基础上增加如下功能:**

1. **各个部件的API增加SysCap属性,在SDK生成时为API添加该属性。**
2. **定义手机、PC、儿童表、TV和平板爆款设备类型的SysCap集合。**

![img](https://devpress.csdnimg.cn/e5f73fe2fbdd4fbaa7b2d1470bce2e23.png)

**应用开发时,IDE可根据API的SysCap属性以及应用所选的设备类型对API的调用做静态检查和联想,提升开发者体验。**

## API

### API 分类

| **类型**       | **使用者**         | **提供者**     | **兼容性要求** | **看护手段** |
| -------------------- | ------------------------ | -------------------- | -------------------- | ------------------ |
| **Public API** | **所有应用开发者** | **系统与框架** | **5个API版本** | **XTS**      |
| **Test API**   | **所有应用开发者** | **测试框架**   | **3个API版**   | **待构建**   |
| **System API** | **系统应用开发者** | **系统与框架** | **2个API版**   | **待构建**   |
| **HDI**        | **系统服务**       | **HDF**        | **4个API版**   | **XTS**      |
| **Driver API** | **驱动开发者**     | **HDF**        | **不承诺**     | **否**       |
| **Inner API**  | **系统部件**       | **系统部件**   | **不承诺**     | **否**       |

### API与元信息

**所有Public API需要通过** `@system`,`@syscap` 标记API相关元信息,但是System API因为不涉及兼容性,所以不要求。

### public API 和 system API 的差异

**Public API**:OpenHarmony 对所有应用开发者公开的 API。 **System API**:提供给系统特权应用使用的 API,普通应用无法使用。

| **类型**       | **提供者**     | **使用者**         | **兼容性要求** | **看护手段** | **资料是否体现** |
| -------------------- | -------------------- | ------------------------ | -------------------- | ------------------ | ---------------------- |
| **Public API** | **系统与框架** | **所有应用开发者** | **5个API版本** | **XTS**      | **是**           |
| **System API** | **系统与框架** | **系统应用开发者** | **不承诺**     | **待构建**   | **暂无要求**     |

### public SDK 和 full SDK 的差异

**SDK 打包生成两个版本,public 版本和 full 版本,其中 public 版本不包含 system API,full 版本包含 public API 和 system API。IDE 默认下载的 SDK 版本为 public 版本,若 OEM 厂商开发者需要 full 版本,则需要自行从官网下载后,替换到 SDK 安装目录。**

**在 EMUI 和 OH API 8 及以前的版本中,API 在系统 API 定义上遵循了安卓的定义。**

| **SDK 版本** | **是否包含 system API** | **是否可以通过 IDE 下载** | **官网是否可以下载** |
| ------------------ | ----------------------------- | ------------------------------- | -------------------------- |
| **public**   | **否**                  | **是**                    | **是**               |
| **full**     | **是**                  | **否**                    | **是**               |

**系统应用开发者、OEM厂商,开发系统应用,需要在官网下载 full 版本的 SDK 后,替换 IDE 默认下载的 public 版本。**

### System API 在 SDK 中的标记

**通过在 API 的 JSDOC 中标记 @systemapi 来标记系统 API。**

```
/**
* Provides methods to operate or manage Wi-Fi.
* @since 7
* @syscap SystemCapability.Communication.WiFi
*/
declare namespace wifi {
   /**
    * Enables Wi-Fi.
    * @return Returns {@code true} if the operation is successful; returns {@code false} otherwise.
    * @permission {@code ohos.permission.SET_WIFI_INFO} and {@code ohos.permission.MANAGE_WIFI_CONNECTION}
    * @systemapi Hide this for inner system use.
    */
   function enableWifi(): boolean;
```

## SysCap

### 系统能力与API

* **SysCap,全称SystemCapability,即系统能力,指操作系统中每一个相对独立的特性,如蓝牙,WIFI,NFC,摄像头等,都是系统能力之一。**
* **每个系统能力对应多个 API,这些 API 绑定在一起,随着目标设备是否支持该系统能力共同存在或消失,也会随着 IDE 一起提供给开发者做联想。**

![syscap-api1](https://devpress.csdnimg.cn/7216ec4fbd1740928dbf2e025715c732.png)

### 部件定义

**通常,模块(Module)是个泛化的概念,主要指在逻辑架构视图中的功能模块,强调代码级复用。**

**组件(Component),主要指在部署视图中可独立加载、部署和运行的二进制软件实体,强调封装和二进制级复用。**

**OpenHarmony参考机械装配领域零部件的概念,在软件架构设计中引入了部件(Part)的概念。部件是指在部署视图中具有相对独立性、能完成一定功能的可独立交付,但是不能独立部署的软件实体。**

**部件是OpenHarmony系统能力的基本单元,以源码为划分依据,具有独立的文件和目录,在不同的设备上可实例化为不同的库或二进制文件。从系统角度看,凡是运行在OpenHarmony上的软件都可以定义为部件。子系统一般是由一个或多个部件构成的。通过组装OpenHarmony部件,就能方便地构建出一个与设备硬件能力最匹配且具备分布式能力的系统。综上所述,子系统划分部件的原则:**

1. **具备独立的代码目录和编译脚本,具备独立的仓,可独立下载,可独立编译出库和二进制**
2. **具备独立测试验证能力**
3. **具备部署能力,不带入该部件的实例化的库和二进制,只会引起部件能力的缺失,不会引起系统的异常**
4. **推荐与硬件能力相关的子系统,可根据硬件配置的常见组合,将硬件配套的子系统分解成部件,例如WIFI部件,NFC部件,GPS部件**
5. **插件化是典型的部件化的设计,例如类似GStreamer,source/decoder plugin都是可以根据产品实际需要来部署**
6. **如果部件可以拆出作为原部件的补充功能模块,并向应用提供API,称这类功能模块为****子部件**,跟随父部件一起部署,无法独立部署。子部件依赖父部件,但父部件不允许依赖子部件
7. **被部件依赖的三方开源库以及子系统内部由于复用等原因拆分的基础部件也为部件,称这类部件为****依赖部件**,在部件的deps中需指定 依赖部件,依赖部件不需要主动配置裁剪,跟随部件一起部署

### 部件化Capability模型

**系统可通过部件的配置裁剪去定义,所以需要通过System Capability(简写为SysCap)来定义配置裁剪后的系统能力:**

1. **不是所有的部件都需要定义System Capability,只有对应用提供API 且 是多设备部署非最小系统必须的(可能被裁剪的) 部件才采用需要定义System Capability。**
2. **部件内也可以具备功能裁剪的能力,但不能引起部件API的变化,并需要提供具体功能是否可被使用的检查方法,如checkFunc(xx).**
3. **SysCap定义格式采用: “SystemCapability.分类.特性.子特性(可选)”格式定义,如SystemCapability.Media.Camera , SystemCapability.Media.Camera.Front。**
4. **SysCap定义要区分特性/feature(SystemCapability.cat.feature)和子特性/subfeature(SystemCapability.cat.feature.subfeature)。Feature 和 subFeature之间不是包含关系而是叠加关系,需要和子部件对应,也就是子特性是父特性的补充。**

### 产品与应用兼容性设计

**使用两个ID来标识,产品具有的OS能力,应用依赖的OS能力**

* **PCID: Product Compatibility ID,产品兼容性标识,南向设备用以标记设备支持的最小集和选配的系统能力。**
* **RPCID: Required Product Compatibility ID,要求产品兼容性标识,北向应用用以标记应用静态依赖的系统能力。**

**设备类型(DeviceType)相当于一个规定值的PCID。应用开发者可以在IDE选择设备类型或者自定义某个PCID的设备进行应用开发。**

## SysCap 与 API 的关系

### SysCap的定义

**SysCap:系统能力即SystemCapability,是部件提供的系统能力。当某个部件在某种设备类型上未部署时,开发者可以通过检测hasSystemCapapability(SystemCapability.xxx)方式确定应用行为。**

**SysCap定义格式建议采用“SystemCapability.Subsystem.部件能力.子能力(可选)”大驼峰格式定义,如SystemCapability.Media.Camera , SystemCapability.Media.Camera.Front。**

**能力和子能力之间不是包含关系 而是 叠加关系。子能力是部件能力的扩展和增强, 默认子能力依赖于部件能力,子能力部署必须依赖于部件能力同时部署。同一个API只能归属到唯一的部件能力或子能力,不能同时归属两个能力,也不能同时归属部件能力和子能力。** **正例:SystemCapability.Net.Wifi.Wifi\_p2p 是 SystemCapability.Net.Wifi的增强。** **反例:hilog\_lite只提供本地日志功能,hilog同时提供本地日志+网络日志功能。** **正确的方式应该是:SystemCapbility.Dfx.Hilog(只提供本地日志能力) 和 SystemCapability.Dfx.Hilog.Remote(叠加支持网络日志能力)。** **如果将来在本地日志能力的基础上扩展跨设备保存日志能力,则可以新增定义 SystemCapability.Dfx.Hillog.RemoteDevice。** **部署组合形式包括: hilog、 hilog + hilog.remote、 hilog + Hillog.RemoteDevice 或 Hilog + Hilog.Remote + Hillog.RemoteDevice。** **不同的能力之间或不同子能力之间也不能是包含关系, 而是并列关系, 无隐式的依赖关系(允许部件之间显式定义依赖关系)。** **如,上例中的hilog.remote 和 hillog.remoteDevice之间为并列关系。**

**每个部件对应一个或多个 SysCap,每个 SysCap 对应多个 API,这些 API 绑定在一起,随着目标设备是否支持该 SysCap 共同存在或消失。**

**SysCap与API的关系:提供API的部件必须定义SysCap,定义了SysCap的部件不一定有API。**

**API 按 SysCap 分类是正交的,不会出现一个 API 同时属于多个 SysCap 的情况,另外,API 的新增,变更,废弃都不影响其所在的 SysCap 本身的功能。**

**比如,软总线基础通讯子系统,包含蓝牙,Wifi,NFC,位置服务等部件,在蓝牙部件下,存在一个 SysCap,SystemCapability.Communication.Bluetooth,在该 SysCap 下有蓝牙相关的 API 集合。**

![syscap-api2](https://devpress.csdnimg.cn/7c74f2b715b348ddacf34101472d95c7.png)

### API 对应 SysCap 的标识方法

**每个 API 通过在 JS DOC 中添加自定义标签 @syscap {SysCap 名称} 的方式来标记该 API 属于哪个 SysCap。**

**@syscap 若标记在 d.ts 中的父节点,则其下所有的 API 都属于该 SysCap。**

```
// 软总线短距通信子系统,其部件位置服务部件的获取当前位置的 API,其声明需要标记 @syscap SystemCapability.Location.Location
declare namespace geolocation {
   /**
    * obtain current location
    * @since 7
    * @syscap SystemCapability.Location.Location
    * @param callback Indicates the callback for reporting the location result.
    */
   function getCurrentLocation(request: CurrentLocationRequest, callback: AsyncCallback<Location>) : void;
   function getCurrentLocation(callback: AsyncCallback<Location>) : void;
   function getCurrentLocation(request?: CurrentLocationRequest) : Promise<Location>;
}
```

### PCID和RPCID

* **PCID** **系统能力区分BCG/OCG/PCG等不同的属性组,在面向多设备部署时,支持采用“BCG+OCG+PCG”方式定义特定设备的系统能力。**

![img](https://devpress.csdnimg.cn/c0087ff2b30445259bbcaa21325b6f85.png)

**PCID属性如下:**

| **API Version(API版本号)**                                                                     | **BCG(Base Components Group - 基本组件组)**                                                                                                                                           | **MID(Manufacturer ID,厂商ID)**                                                                                                                                                            | **OCG(Optional Components Group - 可选组件组)**                                                                                                             | **PCG(Product Components Group - 产品组件组,OEM厂商使用)**                                                                                                                                                          |
| ------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **范围:bit0\~bit15说明:1、PCID中取设备开发采用的OpenHarmony系统系统的API Version,bit15固定0** | **范围:bit16\~bit31说明:1、bit含义--bit16: mini system--bit17: small system--bit18: standard system--bit19\~bit31: reserved2、PCID中,只能某一个bit设置为1,表示此系统类型,默认全0** | **范围:bit32\~bit63说明:1、此字段用以标识一个唯一的厂家信息,如果不存在扩展系统能力,则此字段写02、此字段在OEM提交认证后,如果涉及扩展的系统能力,由兼容性认证管理平台统一分配一个非0值。** | **范围:采用TLV格式封装T---SysCap Type,共16bits,值为0表示此SysCap为系统定义的系统能力。L---Length,16bitsV---Value,≥16bits说明:1、支持的SysCap才写入。** | **范围:采用TLV格式封装T---SysCap Type,共16bits,值为1表示OEM扩展的系统能力。L---Length,16bitsV---Value,≥16bits说明:1、此部分由OEM定义和维护,并在兼容性认证时提交给兼容性认证管理平台;2、支持的SysCap才写入。** |

### PCID编码-生成PCID

**OEM厂商完成部件化拼装后,编译构建搜集PCID相关的信息并生成 ****PCID.json** 文件作为PCID编码的输入,该文件内容示例如下:

```
# PCID.json
{
 "product": "ipcamera",
 "api_version": 8,
 "system_type": "standard",
 "manufacturer_id": 123456,
 "syscap": {
   "os": [
     "SystemCapability.Communication.NFC.Core"
   ]
  }
}
```

**按以下步骤生成PCID文件:**

1. **进入sdk目录的toolchains文件夹中,3.0.0.9\\toolchains\\5.0.1.0,在对应版本的文件夹下找到syscap\_tool.exe。**
2. **将PCID.json文件放在此文件夹下。**
3. **cmd进入此文件夹执行下面的命令即可得到**<product>**.sc文件**
   ```
   syscap_tool -P -e -i ./PCID.json
   ```

### PCID解码

**使用上面PCID编码生成的PCID(**<product>**.sc文件),按以下步骤进行PCID解码:**

1. **继续**[PCID编码-生成PCID](https://laval.csdn.net/6480214e6 ... CID?login=from_csdn)的步骤,cmd进入syscap\_tool.exe所在的文件夹
2. **此时存在PCID编码生成的PCID(**<product>**.sc文件),执行下面的命令:**

   ```
   syscap_tool -P -d -i ./ipcamera.sc
   ```

   **即可得到**<product>**.json文件:**

   ```
   {
     "product": "ipcamera",
     "api_version": 7,
     "manufacturer_id": 123456,
     "system_type": "standard",
     "syscap": {
       "os":[
           "SystemCapability.Hiviewdfx.Hilog",
           "SystemCapability.Communication.Softbus"
       ]
     }
   }
   ```

### RPCID编码

**应用syscap配置文件syscap.json文件,内容示例如下:**

```
{
 "api_version": 7,
  "syscap": [
     "SystemCapability.Hiviewdfx.Hilog",
     "SystemCapability.Communication.Softbus",
     "SystemCapability.Hisicon.Flashlight"
  ]
}
```

**按以下步骤进行PCID解码:**

1. **参考**[PCID编码-生成PCID](https://laval.csdn.net/6480214e6 ... CID?login=from_csdn)的步骤,cmd进入syscap\_tool.exe所在的文件夹
2. **将syscap.json放在此文件夹下,执行以下命令即可得到<rpcid.sc>文件:**
   ```
   syscap_tool -R -e -i ./syscap.json
   ```

### RPCID解码

**使用上面**[RPCID编码](https://laval.csdn.net/6480214e6 ... %81?login=from_csdn)生成的<rpcid.sc>文件,按以下步骤进行RPCID解码:

1. **cmd进入syscap\_tool.exe所在的文件夹**
2. **此时存在RPCID编码生成的<rpcid.sc>文件,执行下面的命令:**

   ```
   syscap_tool -R -d -i ./rpcid.sc
   ```

   **即可得到rpcid.json文件:**

   ```
   {
     "api_version": 7,
     "syscap": [  
         "SystemCapability.Hiviewdfx.Hilog",
             "SystemCapability.Communication.Softbus",                                                                 "SystemCapability.Hisicon.Flashlight"
     ]
   }
   ```

### PCID,RPCID 与 SysCap 的关系

**PCID**采用 BCG(Base Components Group)/OCG(Optional Components Group)/PCG(Product Components Group,预留给OEM)定义特定设备的系统能力。其中,SysCap 是 PCID 的一部分,也是 RPCID 的一部分。对于 SDK,只使用 SysCap 集合,不使用其它字段。

**下面是 IDE 通过 PCID 生成 SysCap 集合和 IDE 通过应用使用的 API 涉及的 RequiredSysCap 集合生成 RPCID 的过程。**

![img](https://devpress.csdnimg.cn/39061ed154a04c03b211f82f4b699233.png)

## 设备与 SysCap

### 爆款设备与 N 设备

**每个设备根据其硬件能力,对应不同的 SysCap 集合。**

**SDK 将设备分为两组,爆款设备和 N 设备。**

**爆款设备为 phone,tablet,wearable,litewearable,tv,car 六种爆款设备,后续可根据生态的拓展增加新的类型,每种爆款设备定义其对应的 SysCap 集合。**

**N 设备为南向自定义类型的设备,在现阶段,微波炉,油烟机等设备属于 N 设备,后面随着生态的发展,N 设备的能力成为业界标准可成为爆款设备。**

**爆款设备由 OpenHarmony 定义其 SysCap 集合,定义存放在 SDK 中,N 设备由厂家定义其 SysCap 集合,并以 PCID 的方式提供给开发者。**

![img](https://devpress.csdnimg.cn/180a2b8a4b874f4aad67112f72f7d9b5.png)

### 爆款设备能力的定义

**在 SDK 根目录下新建 device-define 目录,放置爆款设备的 SysCap 集合的定义,每个爆款设备的定义由一个 json 文件承载。**

**SDK 是 OH 系统中唯一存放设备定义的模块,后续新增、修改、删除爆款的定义都需要从 SDK 中修改。**

**目录结构如下:**

```
# 目录结构
interface/sdk-js
|-- api
    |-- @ohos.xxx.d.ts
    |-- device-define
        |-- phone.json
        |-- tablet.json
        |-- wearable.json
        |-- litewearable.json
        |-- tv.json
        |-- car.json
```

**每个配置文件中,通过 SysCaps 数组声明该设备支持的部件列表。**

```
/* phone.json SysCaps 声明 */
{
    "SysCaps": [
        "SystemCapability.Location.Location",
        "SystemCapability.Telephony.DCall",
        "SystemCapability.Communication.WiFi",
        "SystemCapability.Communication.Bluetooth",
        "SystemCapability.Communication.NFC",
        "...",
    ]
}
```

### N 设备能力的定义

**N 设备支持的 SysCap 集合,不会保存在 SDK 中,而是由厂商给出该设备的 PCID,其中包含了厂家对该设备的 SysCap 集合的定义,IDE 通过 PCID 转换工具生成对应的 SysCap 集合,同爆款设备一样,为开发者提供 API 的联想。**

### 设备与 SDK 能力的对应

**SDK 提供全量的 API 给 IDE,IDE 通过开发者的项目支持的设备,筛选该设备支持的 API 提供给开发者做联想。**

**每个设备,无论是爆款还是 N 设备,都有其能力的 SysCap 的集合,IDE 根据 SysCap 集合,为开发者提供该设备支持的 API。**

![img](https://devpress.csdnimg.cn/b85a3fff07ae4afaa395e0ef04004666.png)

## 应用与 SysCap

### 应用 RequiredSysCap 集合

**RequiredSysCap 是应用的一个属性,表示应用使用了全部的 API 涉及的 SysCap 集合,在开发爆款单设备应用时,其默认值为该爆款设备的 SysCap 结合。**

**开发者也可以通过修改 syscap.json 文件对 RequiredSysCap 集合进行修改。**

**对 RequiredSysCap 修改要非常谨慎,因为应用打包时,工具链会根据这个字段生成该应用的 RPCID,RPCID 决定了该应用在应用市场上是否能在对应的设备上分发。**

#### syscap.json

**syscap.json 放在工程目录下与 config.json 并列的位置。应用在发布打包时,会根据文件内容生成应用的 RPCID。**

```
# syscap.json在项目中的位置
|-- entry
    |-- src
        |-- main
            |-- js
            |-- resources
            |-- config.json
            |-- syscap.json
```

**该文件可为空,为空时默认应用使用的 RequiredSysCap 集合与 config.json 中 deviceType 中设备提供的 SysCap 集合相等,若是跨设备应用,默认与多个设备的 SysCap 集合的交集相等。**

**文件内容包含3个关键配置,分别为 base,development 和 product。**

**base 作为 SysCap 集合的基准值,对于单设备应用开发,爆款设备,IDE会从 config.json 中同步 deviceType,N设备,SysCaps 默认配置为该 N 设备的 SysCap 集合;对于跨设备应用开发,同时支持爆款设备和N设备,deviceType 和 sysCaps 可同时配置。**

**对于跨设备开发,IDE 会对 base 中所配置的所有设备的SysCaps 集合取并集作为联想提示,取交集作为生成 RPCID。**

**除此以外,开发者可以通过 development 修改可联想的 API 范围,和通过 production 修改 RequiredSysCap,**

**development 中配置 IDE 可用于联想的 SysCap 所使用的 API,默认为 base 中所有 SysCap 包含的 API,可通过 addedSysCaps 进行添加。**

**product 中配置,会生成应用的 RequiredSysCap 集合,从而用来生成应用的 RPCID,RequiredSysCap 集合默认为 base 中所有设备 SysCap 集合的交集,可使用 addedSysCaps 和 removedSysCaps 来添加和删除。使用 addedSysCaps 要特别慎重,会导致应用商店无法分发的原爆款设备上。**

**由于该配置项比较复杂,后续 IDE 可考虑通过图形界面配置。**

**下面是一个手机应用,在爆款手机设备支持的 SysCap 能力基础上,支持 NFC 的 API 联想,在应用支持 NFC 但是不支持 Wifi 的例子。**

```
/* config.json */
{
  "module": {
    "deviceType": [
      "phone"
    ],
    ...
  }
}
```

```
/* syscap.json */
{
    "devices": {  /* 由 IDE 自动生成,开发者不需要修改。 */
        "general": [
            "phone",
            "tv",
            "..."
        ],
        "custom": [{        /*厂家自定义设备*/
            "xx油烟机": [  /* 这里的“xx油烟机”是 productId */
                "SystemCapability.Ability.AbilityBase",
                "..."
            ]
        }, {
            "某个N设备": [
                "SystemCapability.Ability.AbilityBase",
                "..."
            ]
        }]
    },
    "development": {   /* 用于 IDE 联想 */
        "addedSysCaps": [
            "SystemCapability.Communication.NFC.Core"
        ]
    },
    "production": {   /* 用于生成 RPCID */
        "addedSysCaps": [
            "SystemCapability.Communication.NFC.Core" /* 慎重添加,会导致应用商店无法分发到爆款手机设备 */
        ],
        "removedSysCaps": [ //当该要求能力集为某设备的子集时,应用才可被分发到该设备上
            "SystemCapability.Communication.WiFi.Core"
        ]
    }
}
```

### 单设备应用开发支撑

**应用 RequiredSysCap 集合与设备 SysCap 集合相等,建议开发者只使用上述 SysCap 定义的 API 开发应用。**

**若应用在 syscap.json 中的 production 中添加了不在上述 SysCap 集合中的 API,则不能在该设备上运行。若应用需要使用额外的 SysCap 能力,又不希望影响分发,则不要在 prodution 中添加该 SysCap,且为了保证运行时不出现异常,使用前必须对该 API 所在的模块是否存在进行判断。**

![img](https://devpress.csdnimg.cn/cf709b7f31c64135a44cf1f97cb1f28b.png)

### 多设备应用开发支撑

**IDE 需要支撑应用的 API 是多设备 SysCap 集合的合集。应用的 RequiredSysCap 应是多设备 SysCap 集合的交集。**

**应用使用交集外的 SysCap 中的 API,都需要使用 hasCapability 函数进行判断。**

![img](https://devpress.csdnimg.cn/b9b20a6b560542359cc1947981dcd838.png)

### 全局 CanIUse() 方法

**定义**

```
declare canIUse(sysCap: string): boolean;
```

**说明**

1. **canIUse 为全局方法,不需要 import 即可使用。**
2. **开发者可覆盖该引用,覆盖后由开发者自行处理并承担后果。**
3. **canIUse 为同步方法,需要保证实现的性能。**
4. **参数 sysCap 为 SystemCapability 的字符串,如 SystemCapability.Location.Location.Core。**
5. **返回值为布尔值,true 表示该设备支持,可以使用,反之为 false。**
6. **后续会考虑,参数除了支持 SysCap 外,也会支持模块名,如 @ohos.geolocation。**

**CanIUse() 的使用**

```
import geolocation from '@ohos.geolocation';
const isLocationAvailable = canIUse('SystemCapability.Location.Location');
if (isLocationAvailable) {
    geolocation.getCurrentLocation((location) => {
        console.log(location.latitude, location.longitude);
    });  
} else {
    console.log('该设备不支持位置信息');
}
```

**或者开发者可通过 import 的方式将模块导入,若当前设备不支持该模块,import 的结果为 undefined,开发者在使用其 API 时,需要判断其是否存在。**

```
import geolocation from '@ohos.geolocation';

if (geolocation) {
        geolocation.getCurrentLocation((location) => {
                console.log(location.latitude, location.longitude);
        });
} else {
        console.log('该设备不支持位置信息');
}
```

### 不同设备相同能力的差异检查

**即使是相同的系统能力,在不同的设备下,也会有能力的差异。比如同是摄像头的能力,平板设备优于智能穿戴设备。**

```
import userAuth from '@ohos.userIAM.userAuth';

const authenticator = userAuth.getAuthenticator();
const result = authenticator.checkAbility('FACE_ONLY', 'S1');

if (result == authenticator.CheckAvailabilityResult.AUTH_NOT_SUPPORT) {
        console.log('该设备不支持人脸识别');
}
//强行调用不支持的 API 会返回错误信息,但不会出现语法错误。
authenticator.execute('FACE_ONLY', 'S1', (err, result) => {
        if (err) {
                console.log(err.message);
                return;
        }
})
```

### 设备间的SysCap差异如何产生的

**设备的SysCap因产品解决方案厂商拼装的部件组合不同而不同,整体流程如下图:**

![img](https://devpress.csdnimg.cn/dd3b3d6b028445f9918d1bd0d7e2f5d5.png)

1. **一套 OpenHarmony 源码由可选和必选部件集组成,不同的部件为对外体现的系统能力不同,即部件与 SysCap 之间映射关系。**
2. **发布归一化的 SDK,API 与 SysCap 之间存在映射关系。**
3. **产品解决方案厂商按硬件能力和产品诉求,可按需拼装部件。**
4. **产品配置的部件可以是 OpenHarmony 的部件,也可以是三方开发的私有部件,由于部件与SysCap间存在映射,所有拼装后即可得到该产品的SysCap集合。**
5. **SysCap集编码生成 PCID (Product Compatibility ID, 产品兼容性标识),应用开发者可将 PCID 导入 IDE解码成SysCap ,开发时对设备的SysCap差异做兼容性处理。**
6. **部署到设备上的系统参数中包含了 SysCap 集,系统提供了native的接口和应用接口,可供系统内的部件和应用查询某个 SysCap 是否存在。**
7. **应用开发过程中,应用必要的 SysCap 将被编码成 RPCID(Required Product Compatibility ID),并写入应用安装包中。应用安装时,包管理器将解码 RPCID 得到应用需要的 SysCap,与设备当前具备的 SysCap 比较,若应用要求的 SysCap 都被满足,则安装成功。**
8. **应用运行时,可通过 canIUse 接口查询设备的 SysCap,保证在不同设备上的兼容性。**

## 包管理子系统与 SysCap

**应用安装时包管理对应用配置的SysCap进行检查,当系统具备的SysCap的集合大于等于应用所需的SysCap时安装成功,否则安装失败。**

**1)使用SysCap编解码工具将应用的RPCID解码成应用所需的SysCap集。**

**2)调用init的SysCap查询接口得到系统的SysCap集。**

**3)包管理对应用所需的SysCap与系统当前具备的SysCap集进行匹配。**

## IDE子系统与 SysCap

**IDE子系统为应用开发提供两大类功能:**

**1)API联想和静态检查**

**2)生成应用的RPCID**

**设备类型不同,IDE获取设备的SysCap和应用配置SysCap的有所区别:**

**1)N设备:设备的SysCap通过用户导入设备PCID和解码得到。应用的配置文件中,deviceType设置为空,所需的SysCap通过requiredSysCap进行全量定义。**

**2)1+8设备:设备的SysCap通过应用配置的deviceType和SDK定义的对应的SysCap集得到。应用的配置文件中,deviceType设置不为空,如果需要对应设备类型所包含的SysCap集之外的能力,以增量的方式写入requiredSysCap。**

### PCID导入

**DevEco Studio 工程支持 PCID 的导入。导入的 PCID 文件解码后输出的 syscap 会被写入 syscap.json 文件中。**

**在工程目录右键后选择 Import Product Compatibility ID,即可上传 PCID 文件并导入至 syscap.json 中。**

**PCID文件生成参考**[PCID编码-生成PCID](https://laval.csdn.net/6480214e6 ... CID?login=from_csdn)

![img](https://devpress.csdnimg.cn/b617423cd2ee4fa390486dfa1a7fccef.gif)

## 设备认证和应用市场

**设备厂商在设备认证时提供PCID,认证中心基于PCID中包含的SysCap进行认证,认证通过后将PCID与设备token映射,并提供给设备厂商。**

应用市场在分发设备时,发送设备token给认证中心,认证中心返回PCID后与应用配置的SysCap进行匹配决定是否分发。

![img](https://devpress.csdnimg.cn/55ac6ef784104e8589ae77f6b346034b.png)
[/md]




欢迎光临 OpenHarmony开发者论坛 (https://forums.openharmony.cn/) Powered by Discuz! X3.5