Stage模型基本概念:
- AbilityStage
每个Entry或Feature HAP在运行期都有一个AbilityStage实例,当HAP代码首次加载时创建。
- UIAbility组件和ExtensionAbility组件
- UIAbility: 包含UI界面的应用组件,用于与用户交互。例如,图库应用展示图片瀑布流。其生命周期包括创建、销毁、前台、后台等状态。
- ExtensionAbility: 面向特定场景的应用组件。开发者使用其派生类,如FormExtensionAbility(卡片场景)和WorkSchedulerExtensionAbility(闲时任务场景)。派生类实例由用户触发创建,系统管理其生命周期。
- WindowStage
每个UIAbility实例绑定一个WindowStage实例,作为应用进程内窗口管理器,包含一个主窗口,为ArkUI提供绘制区域。
- Context
在Stage模型上,Context及其派生类提供运行期可调用的能力。UIAbility和ExtensionAbility派生类都有各自的Context类,继承自基类Context,提供不同能力。
Stage模型开发流程:
任务 | 简介 | 相关指导 |
---|---|---|
应用组件开发 | 本章节介绍了如何使用Stage模型的UIAbility组件和ExtensionAbility组件开发应用。 | - 应用/组件级配置 - UIAbility组件 - ExtensionAbility组件 - AbilityStage组件容器 - 应用上下文Context - 组件启动规则 |
了解进程模型 | 本章节介绍了Stage模型的进程模型以及几种常用的进程间通信方式。 | 进程模型概述 |
了解线程模型 | 本章节介绍了Stage模型的线程模型以及几种常用的线程间通信方式。 | 线程模型概述 |
任务管理 | 本章节介绍了Stage模型中任务管理的基本概念和典型场景。 | - 任务管理场景介绍 - 任务管理与启动模式 - 页面栈和任务链 |
应用配置文件 | 本章节介绍Stage模型中应用配置文件的开发要求。 | Stage模型应用配置文件 |
Stage模型应用组件:
1.应用/组件级配置:
开发应用时,需配置应用的包名、图标等标识特征属性。本文概述了关键配置标签。图标和标签分为应用图标/标签和入口图标/标签,分别在app.json5和module.json5文件的icon和label标签中配置。应用图标和标签用于设置应用,如应用列表;入口图标显示于设备桌面,支持多个入口图标和标签,点击后进入相应UIAbility界面。
2.UIAbility组件:
UIAbility组件是一种包含UI界面的应用组件,主要用于和用户交互。
UIAbility组件是系统调度的基本单元,为应用提供绘制界面的窗口;一个UIAbility组件中可以通过多个页面来实现一个功能模块。每一个UIAbility组件实例,都对应于一个最近任务列表中的任务。
声明配置:
为使应用能够正常使用UIAbility,需要在module.json5配置文件的abilities标签中声明UIAbility的名称、入口、标签等相关信息
{
"module": {
// ...
"abilities": [
{
"name": "EntryAbility", // UIAbility组件的名称
"srcEntry": "./ets/entryability/EntryAbility.ts", // UIAbility组件的代码路径
"description": "$string:EntryAbility_desc", // UIAbility组件的描述信息
"icon": "$media:icon", // UIAbility组件的图标
"label": "$string:EntryAbility_label", // UIAbility组件的标签
"startWindowIcon": "$media:icon", // UIAbility组件启动页面图标资源文件的索引
"startWindowBackground": "$color:start_window_background", // UIAbility组件启动页面背景颜色资源文件的索引
// ...
}
]
}
}
UIAbility组件生命周期:
当用户打开、切换和返回到对应应用时,应用中的UIAbility实例会在其生命周期的不同状态之间转换。UIAbility类提供了一系列回调,通过这些回调可以知道当前UIAbility实例的某个状态发生改变,会经过UIAbility实例的创建和销毁,或者UIAbility实例发生了前后台的状态切换。
包括Create、Foreground、Background、Destroy四个状态
UIAbility组件基本用法
UIAbility启动时需指定加载页面,否则可能出现白屏。可通过WindowStage
对象的loadContent()
方法在onWindowStageCreate()
回调中设置启动页面。
3.应用组件跨设备交互(流转)
随着全场景多设备的生活方式不断深入,不同设备都能在适合的场景下提供良好的体验,例如手表可以提供及时的信息查看能力,电视可以带来沉浸的观影体验。
但是,每个设备也有使用场景的局限,当多个设备通过分布式操作系统能够相互感知、进而整合成一个超级终端时,设备与设备之间就可以取长补短、相互帮助,为用户提供更加自然流畅的分布式体验。
跨多设备的分布式操作可以统称为流转;根据使用场景的不同,流转又分为跨端迁移和多端协同两种具体场景。
基本概念
-
流转
泛指跨多设备的分布式操作。流转能力打破设备界限,多设备联动,使用户应用程序可分可合、可流转,实现如跨设备编辑邮件、多设备协同健身、多屏游戏等分布式业务。流转按照使用场景可分为跨端迁移和多端协同。
-
跨端迁移
在用户使用设备的过程中,当使用情境发生变化时(例如从室内走到户外或者周围有更合适的设备等),之前使用的设备可能已经不适合继续当前的任务,此时,用户可以选择新的设备来继续当前的任务,原设备可按需决定是否退出任务,这就是跨端迁移场景。
常见的跨端迁移场景实例:在平板上播放的视频,迁移到智慧屏继续播放,从而获得更佳的观看体验;平板上的视频应用退出。
在应用开发层面,跨端迁移指在A端运行的UIAbility迁移到B端上,完成迁移后, B端UIAbility继续任务,而A端UIAbility可按需决定是否退出。
-
多端协同
用户拥有的多个设备,可以作为一个整体,为用户提供比单设备更加高效、沉浸的体验,这就是多端协同场景。
- 场景一:两台设备A和B打开备忘录同一篇笔记进行双端协同编辑,在设备A上可以使用本地图库中的图片资源插入编辑,设备B上进行文字内容编辑。
- 场景二:设备A上正在和客户进行聊天,客户需要的资料在设备B上,可以通过聊天软件打开设备B上的文档应用选择到想要的资料回传到设备A上,然后通过聊天软件发送给客户。
流转架构
-
支持远程服务调用等能力,可轻松设计业务。
-
支持多个应用同时进行流转。
-
支持不同形态设备,如平板、智慧屏、手表等
4.Stage模型下进程:
- 应用中(同-Bundle名称)的所有UlAbility、ServiceExtensionAbility和DataShareExtensionAbility均是运行在同一个独立进程(主进程)中, 如下图中绿色部分的“Main Process”
- 应用中(同-Bundle名称)的所有同一类型ExtensionAbility ( 除ServiceExtensionAbility和DataShareExtensionAbility外)均是运行在一个独立进程中,如下图中蓝色部分的“FormExtensionAbilityProcess”、“InputMethodExtensionAbility Process”、其他ExtensionAbility Process。
- WebView拥有独立的渲染进程,如下图中黄色部分的“RenderProcess"
5.Stage模型下的线程:
1.主线程:
- 执行UI绘制。
- 管理主线程的ArkTS引擎实例,使多个UIAbility组件能够运行在其之上。
- 管理其他线程的ArkTS引擎实例,例如使用TaskPool(任务池)创建任务或取消任务、启动和终止Worker线程。
- 分发交互事件。
- 处理应用代码的回调,包括事件处理和生命周期管理。
- 接收TaskPool以及Worker线程发送的消息。
2.TaskPool Worker线程:
- 用于执行耗时操作,支持设置调度优先级、负载均衡等功能,推荐使用。
- 没有线程数量限制-由系统优先级调度
3.Worker线程:
- 最多8个
- 用于执行耗时操作,支持线程间通信。TaskPool与Worker的运作机制、通信手段和使用方法可以参考TaskPool和Worker的对比
TaskPool(任务池)和Worker的作用:
- 是为应用程序提供一个多线程的运行环境,用于处理耗时的计算任务或其他密集型任务。可以有效地避免这些任务阻塞主线程,从而最大化系统的利用率,降低整体资源消耗,并提高系统的整体性能。
子线程和主线程可以通过EventHandler机制进行通信。
EventHandler是鸿蒙用于处理线程间通信的一种机制,它可以通过EventRunner创建新线程,并将耗时的操作放到新线程上执行,既不阻塞原来的线程,又能合理处理任务。
比如主线程使用EventHandler创建子线程,子线程做耗时的下载图片操作,下载完成后,子线程通过EventHandler通知主线程,主线程再更新 UI。
使用EventHandler实现线程间通信的主要流程如下:
- 创建EventRunner:可以选择托管模式(系统自动管理线程的启动和停止)或手动模式(需要自行调用run()方法启动和stop()方法停止线程)。例如创建手动模式的EventRunner:EventRunner runner = EventRunner.create(false);
- 创建EventHandler子类的实例并与EventRunner绑定:MyEventHandler myHandler = new MyEventHandler(runner);
- 投递事件或任务:
-
- 投递InnerEvent事件: 获取InnerEvent事件(通过InnerEvent.get()方法),然后使用EventHandler的postEvent( )方法进行投递。例如:myHandler.postEvent(normalInnerEvent);
- 投递Runnable任务: 直接使用EventHandler的postTask()方法投递Runnable任务。
还有Emitter和Worker等方式用于线程间通信
其中Emitter主要用于线程间的事件同步;Worker是与主线程并行的独立线程,通常用于在新线程中处理耗时操作,但不能直接操作 UI。
使用Emitter进行线程间通信的步骤如下:
- 订阅事件:使用emitter.on(event, callback)方法订阅事件,其中event是定义的事件对象,callback是收到事件后的回调函数。
- 发送事件:使用emitter.emit(event, eventData)方法发送事件,其中event是要发送的事件对象,eventData是事件携带的数据。
使用Worker进行线程间通信的步骤如下:
- 在工程的模块级build-profile.json5文件的buildOption属性中添加配置信息,指定workers对应的脚本文件路径。
- 根据配置创建对应的worker.ts文件,在其中处理来自主线程的消息和向主线程发送消息。
- 在主线程中使用new worker.ThreadWorker("worker.ts 文件路径")创建Worker对象,通过postMessage()方法向Worker线程发送消息,使用onmessage方法处理来自Worker线程的消息,并可根据业务需要调用terminate()方法停止Worker线程。
ArkUI(方舟UI框架):
为应用的UI开发提供了完整的基础设施,包括简洁的UI语法、丰富的UI功能(组件、布局、动画以及交互事件),以及实时界面预览工具等,可以支持开发者进行可视化界面开发
两种开发范式:
针对不同的应用场景及技术背景,方舟UI框架提供了两种开发范式,分别是基于ArkTS的声明式开发范式(简称“声明式开发范式”)和兼容JS的类Web开发范式(简称“类Web开发范式”)。
-
声明式开发范式:采用基于TypeScript声明式UI语法扩展而来的ArkTS语言,从组件、动画和状态管理三个维度提供UI绘制能力。
-
类Web开发范式:采用经典的HML、CSS、JavaScript三段式开发方式,即使用HML标签文件搭建布局、使用CSS文件描述样式、使用JavaScript文件处理逻辑。该范式更符合于Web前端开发者的使用习惯,便于快速将已有的Web应用改造成方舟UI框架应用。
在开发一款新应用时,推荐采用声明式开发范式来构建UI,主要基于以下几点考虑:
-
开发效率: 声明式开发范式更接近自然语义的编程方式,开发者可以直观地描述UI,无需关心如何实现UI绘制和渲染,开发高效简洁。
-
应用性能: 如下图所示,两种开发范式的UI后端引擎和语言运行时是共用的,但是相比类Web开发范式,声明式开发范式无需JS框架进行页面DOM管理,渲染更新链路更为精简,占用内存更少,应用性能更佳。
-
发展趋势:声明式开发范式后续会作为主推的开发范式持续演进,为开发者提供更丰富、更强大的能力。
主要包括:
-
ArkTS
ArkTS是优选的主力应用开发语言,围绕应用开发在TypeScript(简称TS)生态基础上做了进一步扩展。扩展能力包含声明式UI描述、自定义组件、动态扩展UI元素、状态管理和渲染控制。状态管理作为基于ArkTS的声明式开发范式的特色,通过功能不同的装饰器给开发者提供了清晰的页面更新渲染流程和管道。状态管理包括UI组件状态和应用程序状态,两者协作可以使开发者完整地构建整个应用的数据更新和UI渲染。ArkTS语言的基础知识请参考初识ArkTS语言。
-
布局
布局是UI的必要元素,它定义了组件在界面中的位置。ArkUI框架提供了多种布局方式,除了基础的线性布局、层叠布局、弹性布局、相对布局、栅格布局外,也提供了相对复杂的列表、宫格、轮播。
-
组件
组件是UI的必要元素,形成了在界面中的样子,由框架直接提供的称为系统组件,由开发者定义的称为自定义组件。系统内置组件包括按钮、单选框、进度条、文本等。开发者可以通过链式调用的方式设置系统内置组件的渲染效果。开发者可以将系统内置组件组合为自定义组件,通过这种方式将页面组件化为一个个独立的UI单元,实现页面不同单元的独立创建、开发和复用,具有更强的工程性。
-
页面路由和组件导航
应用可能包含多个页面,可通过页面路由实现页面间的跳转。一个页面内可能存在组件间的导航如典型的分栏,可通过导航组件实现组件间的导航。
-
图形
方舟开发框架提供了多种类型图片的显示能力和多种自定义绘制的能力,以满足开发者的自定义绘图需求,支持绘制形状、填充颜色、绘制文本、变形与裁剪、嵌入图片等。
-
动画
动画是UI的重要元素之一。优秀的动画设计能够极大地提升用户体验,框架提供了丰富的动画能力,除了组件内置动画效果外,还包括属性动画、显式动画、自定义转场动画以及动画API等,开发者可以通过封装的物理模型或者调用动画能力API来实现自定义动画轨迹。
-
交互事件
交互事件是UI和用户交互的必要元素。方舟开发框架提供了多种交互事件,除了触摸事件、鼠标事件、键盘按键事件、焦点事件等通用事件外,还包括基于通用事件进行进一步识别的手势事件。手势事件有单一手势如点击手势、长按手势、拖动手势、捏合手势、旋转手势、滑动手势,以及通过单一手势事件进行组合的组合手势事件。
特点
-
开发效率高,开发体验好
- 代码简洁:通过接近自然语义的方式描述UI,不必关心框架如何实现UI绘制和渲染。
- 数据驱动UI变化:让开发者更专注自身业务逻辑的处理。当UI发生变化时,开发者无需编写在不同的UI之间进行切换的UI代码, 开发人员仅需要编写引起界面变化的数据,具体UI如何变化交给框架。
- 开发体验好:界面也是代码,让开发者的编程体验得到提升。
-
性能优越
-
生态容易快速推进 能够借力主流语言生态快速推进,语言相对中立友好,有相应的标准组织可以逐步演进。
整体架构
兼容JS的类Web开发范式的方舟开发框架,包括应用层(Application)、前端框架层(Framework)、引擎层(Engine)和平台适配层(Porting Layer)
-
Application
应用层表示开发者开发的FA应用,这里的FA应用特指JS FA应用。
-
Framework
前端框架层主要完成前端页面解析,并提供MVVM(Model-View-ViewModel)开发模式、页面路由机制和自定义组件等能力。
-
Engine
引擎层主要提供动画解析、DOM(Document Object Model)树构建、布局计算、渲染命令构建与绘制、事件管理等能力。
-
Porting Layer
适配层主要对平台层进行抽象,提供抽象接口,可以对接到系统平台。比如:事件对接、渲染管线对接和系统生命周期对接等。
-
ArkTS 工程目录结构(Stage 模型):
- AppScope > app.json5:应用的全局配置信息。
- entry:HarmonyOS 工程模块,编译构建生成一个 HAP 包。
- src > main > ets:用于存放 ArkTS 源码。
- src > main > ets > entryability:应用/服务的入口。
- src > main > ets > pages:应用/服务包含的页面。
- src > main > resources:用于存放应用/服务所用到的资源文件,如图形、多媒体、字符串、布局文件等。
- src > main > module.json5:Stage 模型模块配置文件,主要包含 HAP 包的配置信息、应用/服务在具体设备上的配置信息以及应用/服务的全局配置信息。
- build-profile.json5:当前的模块信息、编译信息配置项,包括 buildOption、targets 配置等,其中 targets 中可配置当前运行环境,默认为 HarmonyOS。
- hvigorfile.ts:模块级编译构建任务脚本,开发者可以自定义相关任务和代码实现。
- oh_modules:用于存放三方库依赖信息。
- build-profile.json5:应用级配置信息,包括签名、产品配置等。
- hvigorfile.ts:应用级编译构建任务脚本。