鸿蒙应用框架
Ability Kit
Ability Kit(程序框架服务)提供了应用程序开发和运行的应用模型,是系统为开发者提供的应用程序所需能力的抽象提炼,它提供了应用程序必备的组件和运行机制。有了应用模型,开发者可以基于一套统一的模型进行应用开发,使应用开发更简单、高效。
Ability Kit 的特点包括:为复杂应用而设计;支持应用组件级的跨端迁移和多端协同;支持多设备和多窗口形态;以及平衡应用能力和系统管控成本。
UIAbility 是系统调度的最小单元。在设备内的功能模块之间跳转时,会涉及到启动特定的 UIAbility,包括应用内的其他 UIAbility、或者其他应用的 UIAbility(例如启动三方支付UIAbility)。有时,我们需要启动应用内的 Ability 或者启动 UIAbility 的指定页面。具体启动方式的介绍,可以参见官方文档。
UIAbility 的启动分为热启动和冷启动两种方式。冷启动指实例处于完全关闭状态下启动,完整加载所需的资源,会完整调用 OnCreate()
和 OnWindowStageCreate()
;热启动指 UIAbility 已经在前台运行过,并且处于后台的进程未被清理,这种情况下可以快速恢复 UIAbility 实例的状态,并只会调用 onNewWant()
生命周期方法。
Network Kit
Network Kit(网络服务)主要提供以下功能:HTTP 数据请求、Socket 链接、网络连接管理(如多网络连接的管理,网络延迟检测等)和 MDNS 管理等等。使用网络管理模块的相关功能时,需要请求相应的权限。
使用 Request 接口来实现简单的 HTTP 数据请求。Request 接口开发步骤为:首先利用 createHttp()
创建一个 HttpRequest 对象,然后调用该对象的 request()
方法,传入 HTTP 请求的 url 地址和可选参数,发起网络请求,之后根据实际业务解析。当使用完毕时,可以使用 destroy()
对对象进行回收。在此过程中,我们还可以调用 on()
方法,订阅 HTTP 响应头事件,这一接口会比 request()
请求提前返回。与 Request
接口相近的是 requestInStream
接口,他可以订阅 HTTP 流式响应数据事件。
使用 WebSocket 建立服务器与客户端的双向连接。WebSocket 接口的开发步骤是:导入需要的 WebSocket 模块,创建一个 WebSocket 连接并返回对象。订阅 WebSocket 的打开、消息接收、关闭和异常事件等。然后根据 URL 地址,发起 WebSocket 连接。使用完后,主动断开连接。
Socket 连接主要是通过 Socket 进行数据传输(即 IP 地址和端口号),支持 TCP/UDP/Multicast/TLS 协议。应用 TCP/UDP 的开发步骤是:导入所需的 socket 模块,并创建一个 TCPSocket,返回对象。订阅 TCPSocket相关的订阅事件,绑定 IP 地址和端口,连接到制定的端口发送数据。在使用完毕之后管理连接释放资源。
ArkData
运作机制
使用用户首选项(轻量级的配置数据持久化,例如用户的使用习惯、设置等)、键值型数据管理和关系型数据管理来实现数据持久化。提供分布式数据对象、跨应用数据管理和统一数据管理框架的分布式交互服务。此外,还有一部分数据管理服务,主要实现持久化数据跨设备同步、DataShare 静默访问 provider 数据,暂存 DataObject 同步对象数据等。
用户首选项
—般用于记住用户的—些选择,例如终端设置(如位置开关、NFC 开关),用户的使用习惯(如“仅此—次” 、“始终”)等等。用户程序通过 JS 接口调用用户首选项读写对应的数据文件。开发者可以将用户首选项持久化文件的内容加载到 Preferences 实例,其中每个文件唯一对应到一个 Preferences 实例,系统会通过静态容器将该实例存储在内存中,直到主动从内存中移除该实例或者删除该文件。
主要的 API 如下(来自官网文章):
接口原型 | 说明 |
---|---|
getPreferencesSync(context: Context, options: Options): Preferences | 获取Preferences实例。该接口存在异步接口。 |
putSync(key: string, value: ValueType): void | 将数据写入Preferences实例,可通过flush将Preferences实例持久化。该接口存在异步接口。 |
hasSync(key: string): boolean | 检查Preferences实例是否包含名为给定Key的存储键值对。给定的Key值不能为空。该接口存在异步接口。 |
getSync(key: string, defValue: ValueType): ValueType | 获取键对应的值,如果值为null或者非默认值类型,返回默认数据defValue。该接口存在异步接口。 |
deleteSync(key: string): void | 从Preferences实例中删除名为给定Key的存储键值对。该接口存在异步接口。 |
flush(callback: AsyncCallback<void>): void | 将当前Preferences实例的数据异步存储到用户首选项持久化文件中。 |
on(type: 'change', callback: Callback<string>): void | 订阅数据变更,订阅的数据发生变更后,在执行flush方法后,触发callback回调。 |
off(type: 'change', callback?: Callback<string>): void | 取消订阅数据变更。 |
deletePreferences(context: Context, options: Options, callback: AsyncCallback<void>): void | 从内存中移除指定的Preferences实例。若Preferences实例有对应的持久化文件,则同时删除其持久化文件。 |
具体的开发步骤也可以查看官网文章。
键值型数据库
键值型数据库存储键值对形式的数据,当需要存储的数据没有复杂的关系模型,比如存储商品名称及对应价格、员工工号及今日是否已出勤等,由于数据复杂度低,更容易兼容不同数据库版本和设备类型,因此推荐使用键值型数据库持久化此类数据。
主要的 API 如下(来自官网文章):
接口原型 | 描述 |
---|---|
createKVManager(config: KVManagerConfig): KVManager | 创建一个KVManager对象实例,用于管理数据库对象。 |
getKVStore<T>(storeId: string, options: Options, callback: AsyncCallback<T>): void | 指定options和storeId,创建并得到指定类型的KVStore数据库。 |
put(key: string, value: Uint8Array | string | number | boolean, callback: AsyncCallback<void>): void | 添加指定类型的键值对到数据库。 |
get(key: string, callback: AsyncCallback<boolean | string | number | Uint8Array>): void | 获取指定键的值。 |
delete(key: string, callback: AsyncCallback<void>): void | 从数据库中删除指定键值的数据。 |
具体的开发步骤也可以查看官网文章。
关系型数据库
关系型数据库基于 SQLite 组件,适用于存储包含复杂关系数据的场景,比如一个班级的学生信息,需要包括姓名、学号、各科成绩等;又或者公司的雇员信息,需要包括姓名、工号、职位等。由于数据之间有较强的对应关系,复杂程度比键值型数据更 高,此时需要使用关系型数据库来持久化保存数据。
主要的 API 如下(来自官网文章):
接口名称 | 描述 |
---|---|
getRdbStore(context: Context, config: StoreConfig, callback: AsyncCallback<RdbStore>): void | 获得一个RdbStore,操作关系型数据库,用户可以根据自己的需求配置RdbStore的参数,然后通过RdbStore调用相关接口可以执行相关的数据操作。 |
executeSql(sql: string, bindArgs: Array<ValueType>, callback: AsyncCallback<void>):void | 执行包含指定参数但不返回值的SQL语句。 |
insert(table: string, values: ValuesBucket, callback: AsyncCallback<number>):void | 向目标表中插入一行数据。 |
update(values: ValuesBucket, predicates: RdbPredicates, callback: AsyncCallback<number>):void | 根据predicates的指定实例对象更新数据库中的数据。 |
delete(predicates: RdbPredicates, callback: AsyncCallback<number>):void | 根据predicates的指定实例对象从数据库中删除数据。 |
query(predicates: RdbPredicates, columns: Array<string>, callback: AsyncCallback<ResultSet>):void | 根据指定条件查询数据库中的数据。 |
deleteRdbStore(context: Context, name: string, callback: AsyncCallback<void>): void | 删除数据库。 |
具体的开发步骤也可以查看官网文章。
Core File Kit
Core File Kit 提供了设备文件的管理能力。在文件管理套件中,可以按文件所有者的不同,分为应用文件、用户文件和系统文件三种类型;也可以按照文件存储位置的不同,分为本地文件系统和分布式文件系统(即跨设备)。
Core File Kit 使用了沙箱隔离和应用分享两种技术来实现了数据的安全性和一致性的兼顾。对于每个应用,系统会在内部存储空间映射出一个专属的“应用沙箱目录”,它是“应用文件目录”与一部分系统文件(应用运行必需的少量系统文件)所在的目录组成的集合。应用之间可以通过分享 URI(Uniform Resource Identifier)或文件描述符 FD(File Descriptor)的方式,进行文件共享。
各类系统应用或三方应用(即图中的文件访问客户端)若需访问用户文件,如选择一张照片或保存多个文档等,可以通过拉起“文件选择器应用”(FilePicker)来实现。对于设备开发者,还可以按需开发自己的文件选择器或文件管理器应用。这就需要借助文件管理类应用 FileManager 来实现。这一应用不向第三方应用开放。
应用文件
文件所有者为应用的文件,包括应用安装文件、应用资源文件、应用缓存文件等。应用使用及存储的数据以键值对存放,叫做应用文件目录。“应用文件目录”与一部分系统文件组成了应用沙箱目录,这是应用可见目录的最大范围。其中,系统文件是只读的。
应用文件目录的一般结构如下图(源自华为官网)
应用文件分享是应用之间通过分享 URI(Uniform Resource Identifier)或文件描述符 FD(File Descriptor)的方式,进行文件共享的过程。基于 URI 分享方式,应用之间可分享单个文件。文件 URI 的格式为 file://<bundleName>/<path>
,其中 file
是文件 URI
的标志,而 bundleName
是该文件资源的宿主,path
是文件资源在应用沙箱当中的路径。
用户文件
文件所有者为登陆到该终端设备的用户的文件,包括用户私有的图片、视频、音频、文档等。应用对用户文件的创建、访问、删除等行为,需要提前获取用户授权,或由用户操作完成。
用户文件的 URI 一般分为两类:文档类 URI 的格式类型和媒体文件 URI 的类型。文档类的格式为 file://docs/storage/Users/currentUser/<relative_path>/<file_name>
,而媒体类型的格式为 file://media/<media_type>/<id_number>/IMG_datetime_0001/<file_name>
,其中 type
有 Photo
和 Audio
两种选择。
用户需要分享文件、保存图片、视频等用户文件时,开发者可以通过系统预置的文件选择器 FilePicker, 实现该能力。根据用户文件的常⻅类型,选择器分别提供 PhotoViewPicker
、DocumentViewPicker
和 AudioViewPicker
三种选项。
在从网络下载文件到本地、或将已有用户文件另存为新的文件路径等场景下,需要使用 FilePicker 提供的保存用户文件的能力。FilePicker 获取的 URI 只具有临时权限,获取持久化权限需要通过 FilePicker 设置永久授权方式获取。
ArkWeb
ArkWeb(方舟Web)提供了 Web 组件,用于在应用程序中显示 Web ⻚面内容。主要场景为应用集成 Web 页面、浏览器网页浏览以及小程序等。Web 组件为开发者提供了丰富的控制 Web ⻚面能力,譬如 Web ⻚面加载、常用属性与事件、JavaScript 交互、生命周期管理等等。
下面介绍利用 Web 组件进行简单开发的过程:
- 使用 Web 组件进行开发,首先要创建
WebviewController
controller: webview.WebviewController = new webview.WebviewController();
常用的接口如下
接口原型 描述 loadUrl(url: string)
加载网络⻚面或加载本地⻚面。 loadData(data: string)
加载 HTML 格式的文本数据 forward(): void
按照历史栈,前进一个页面。 backward(): void
按照历史栈,后退一个页面。 createNWeb()
支持命令式创建Web组件,这种方式创建的组件不会立即挂载到组件树,即不会对用户呈现(组件状态为Hidden和InActive),开发者可以在后续使用中按需动态挂载。 onLoadIntercept()
点击网⻚中的链接需要跳转到应用内其他⻚面。 更详细的接口介绍,可以参考官方文档。