应用模型
应用模型是系统为开发者提供的应用程序所需能力的抽象提炼,它提供了应用程序必备的组件和运行机制。有了应用模型,开发者可以基于一套统一的模型进行应用开发,使应用开发更简单、高效。
应用模型的构成要素包括:
应用组件
应用组件是应用的基本组成单位,是应用的运行入口。用户启动、使用和退出应用过程中,应用组件会在不同的状态间切换,这些状态称为应用组件的生命周期。应用组件提供生命周期的回调函数,开发者通过应用组件的生命周期回调感知应用的状态变化。应用开发者在编写应用时,首先需要编写的就是应用组件,同时还需编写应用组件的生命周期回调函数,并在应用配置文件中配置相关信息。这样,操作系统在运行期间通过配置文件创建应用组件的实例,并调度它的生命周期回调函数,从而执行开发者的代码。
应用进程模型
应用进程模型定义应用进程的创建和销毁方式,以及进程间的通信方式。
应用线程模型
应用线程模型定义应用进程内线程的创建和销毁方式、主线程和UI线程的创建方式、线程间的通信方式。
应用任务管理模型(仅对系统应用开放)
应用任务管理模型定义任务(Mission)的创建和销毁方式,以及任务与组件间的关系。所谓任务,即用户使用一个应用组件实例的记录。每次用户启动一个新的应用组件实例,都会生成一个新的任务。例如,用户启动一个视频应用,此时在“最近任务”界面,将会看到视频应用这个任务,当用户点击这个任务时,系统会把该任务切换到前台,如果这个视频应用中的视频编辑功能也是通过应用组件编写的,那么在用户启动视频编辑功能时,会创建视频编辑的应用组件实例,在“最近任务”界面中,将会展示视频应用、视频编辑两个任务。
应用配置文件
应用配置文件中包含应用配置信息、应用组件信息、权限信息、开发者自定义信息等,这些信息在编译构建、分发和运行阶段分别提供给编译工具、应用市场和操作系统使用。
应用模型可以理解为HarmonyOS为开发者提供的应用程序开发规范,组织文件入口设置、生命周期、进程线程服务、配置项内容等,具有必备的组件和运行机制,让开发者在统一的模型进行应用开发,更简单、高效。
鸿蒙的一套开发规则
应用组件: 感知力度最大的生命周期
应用进程模型: 初级你不一定感受到,高级一点进程的创建和销毁方式,以及进程间的通信方式。 减少bug、提升性能
应用线程模型: 性能优化了里面干活的,当然你就http走天下也行吧 得学
应用任务管理模型:仅对系统应用开放底层规则
应用配置模型: 感知力度最大的app图标
模型概况
随着系统的演进发展,先后提供了两种应用模型:
FA(Feature Ability)模型:从API 7开始支持的模型,已经不再主推。
Stage模型:从API 9开始新增的模型,是目前主推且会长期演进的模型。在该模型中,由于提供了AbilityStage、WindowStage等类作为应用组件和Window窗口的“舞台”,因此称这种应用模型为Stage模型。
模型开发概述
基于Stage模型开发应用时,在应用模型部分,涉及如下开发过程。
表1Stage模型开发流程
| 任务 | 简介 | 相关指导 |
|---|---|---|
| 应用组件开发 | 本章节介绍了如何使用Stage模型的UIAbility组件和ExtensionAbility组件开发应用。 | - 应用/组件级配置 APP图标/包名 - UIAbility组件 生命周期/数据通信 - ExtensionAbility组件 后面服务卡片学 - AbilityStage组件容器 - 应用上下文Context API会用到 - 组件启动规则 |
| 了解进程模型 | 本章节介绍了Stage模型的进程模型以及几种常用的进程间通信方式。 | 进程模型概述 面试、拔高 |
| 了解线程模型 | 本章节介绍了Stage模型的线程模型以及几种常用的线程间通信方式。 | 线程模型概述 面试、拔高 |
| 应用配置文件 | 本章节介绍Stage模型中应用配置文件的开发要求。 | Stage模型应用配置文件 开发用 |
应用/组件级配置
感知力度最大的 =》应用图标、包名bundleName
应用图标和标签配置
应用图标需要在工程的AppScope目录下的app.json5配置文件中配置icon标签。应用图标需配置为图片的资源索引,配置完成后,该图片即为应用的图标。
应用标签需要在工程的AppScope模块下的app.json5配置文件中配置label标签。标识应用对用户显示的名称,需要配置为字符串资源的索引。
{ "app": { "icon": "$media:app_icon", "label": "$string:app_name" ... } }入口图标和标签配置方式
Stage模型支持对组件配置入口图标和入口标签。入口图标和入口标签会显示在桌面上。
入口图标需要在module.json5配置文件中配置,在abilities标签下面有icon标签。例如希望在桌面上显示该UIAbility的图标,则需要在skills标签下面的entities中添加"entity.system.home"、actions中添加"ohos.want.action.home"。同一个应用有多个UIAbility配置上述字段时,桌面上会显示出多个图标,分别对应各自的UIAbility。
{ "module": { ... "abilities": [ { "icon": "$media:icon", "label": "$string:EntryAbility_label", // 国际化配置 Text($r('app.string.hello')) "skills": [ { "entities": [ "entity.system.home" ], "actions": [ "ohos.want.action.home" ] } ], } ] } }UIAbility组件
概述
UIAbility的设计理念:
原生支持应用组件级的跨端迁移和多端协同。
支持多设备和多窗口形态!!!。
对于开发者而言,可以根据具体场景选择单个还是多个UIAbility,划分建议如下:
如果开发者希望在任务视图中看到一个任务,则建议使用一个UIAbility,多个页面的方式。
如果开发者希望在任务视图中看到多个任务,或者需要同时开启多个窗口,则建议使用多个UIAbility开发不同的模块功能。
例如微信视频号、小程序 苹果系统下永远是一个任务;安卓/华为多个 大家可以自己试试
UIAbility核心配置
为使应用能够正常使用UIAbility,需要在module.json5配置文件的abilities标签中声明UIAbility的名称、入口、标签等相关信息。
{ "module": { ... "abilities": [ // 一个项目可以有多个UIAbility 例如微信 但是第一个是app的图标 { "name": "EntryAbility", // UIAbility组件的名称!!!! 可以用于跳转 "srcEntry": "./ets/entryability/EntryAbility.ets", // 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组件启动页面背景颜色资源文件的索引 ... } ] } }基础使用
1、创建一个页面,并声明路由 main_pages.json
2、创建任务/窗口/Ability 并打开修改他加载的页面 (也就是到底哪一个界面需要单独的窗口打开)
会生成1个文件(修改窗口布局内容 到底是哪一个路由的)、和修改model.json5文件(图片名字等)
import { common, Want } from '@kit.AbilityKit'; @Entry @Component struct Index { private context = getContext(this) as common.UIAbilityContext; build() { Column() { Text('全国领导人大会简章') Text($r('app.string.hello')) Button('打开花小猪小程序').onClick((event: ClickEvent) => { const want: Want = { // Want参数信息 deviceId: '', // deviceId为空表示本设备 bundleName: 'com.example.ability', abilityName: 'MiniProgramAbility', parameters: { id: 1111, other: 2 } }; this.context.startAbility(want); }) } } }启动模式、Want
UIAbility的启动模式是指UIAbility实例在启动时的不同呈现状态。针对不同的业务场景,系统提供了三种启动模式:
singleton(单实例模式)
每次调用startAbility()方法时,如果应用进程中该类型的UIAbility实例已经存在,则复用系统中的UIAbility实例。系统中只存在唯一一个该UIAbility实例,即在最近任务列表中只存在一个该类型的UIAbility实例。
multiton(多实例模式)
multiton启动模式为多实例模式,每次调用startAbility()方法时,都会在应用进程中创建一个新的该类型UIAbility实例。即在最近任务列表中可以看到有多个该类型的UIAbility实例。这种情况下可以将UIAbility配置为multiton(多实例模式)。
specified(指定实例模式)
微信案例
1、布局、声明路由能相互访问
2、创建ability 修改每个入口路径
3、通过Want打开不同的ability (切记不是router去跳转 这玩意局限于单个组件中 打开不同页面 )
信息传递载体Want https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/4_6_u4fe1_u606f_u4f20_u9012_u8f7d_u4f53want-0000001478181153-V2
// import router from '@ohos.router' import common from '@ohos.app.ability.common'; @Entry @Component struct Index { build() { Column() { Text('Index 微信发现页面').fontSize(40) Button('Index2 视频号').onClick(async () => { // router.pushUrl({ url: 'pages/Index2' }) try { // Explicit want with abilityName specified. let want = { deviceId: "", bundleName: "com.example.test1", abilityName: "VideoAbility", parameters: { id: 1111, other: 2 } }; let context = getContext(this) as common.UIAbilityContext; await context.startAbility(want); console.info(`explicit start ability succeed`); } catch (error) { console.info(`explicit start ability failed with ${error.code}`); } }) Button('Index3 小程序').onClick(() => { // router.pushUrl({ url: 'pages/Index2' }) }) } } }生命周期
当用户打开、切换和返回到对应应用时,应用中的UIAbility实例会在其生命周期的不同状态之间转换。UIAbility类提供了一系列回调,通过这些回调可以知道当前UIAbility实例的某个状态发生改变,会经过UIAbility实例的创建和销毁,或者UIAbility实例发生了前后台的状态切换。
UIAbility的生命周期包括Create、Foreground、Background、Destroy四个状态,如下图所示。
图1UIAbility生命周期状态
WindowStageCreate和WindowStageDestroy状态
UIAbility实例创建完成之后,在进入Foreground之前,系统会创建一个WindowStage。WindowStage创建完成后会进入onWindowStageCreate()回调,可以在该回调中设置UI加载、设置WindowStage的事件订阅。
图2WindowStageCreate和WindowStageDestroy状态
数据交互
在实战开发中咱们经常会拉起UIAbility任务,因此出现两个UIAbility任务相互通信的情况,如何传参呢
1、startAbility拉起任务并传参
Button('显示Want:打开花小猪小程序').onClick((event: ClickEvent) => { const want: Want = { // Want参数信息 deviceId: '', // deviceId为空表示本设备 bundleName: 'com.example.ability', abilityName: 'MiniProgramAbility', parameters: { userId: 6, userName: '武大郎' } }; this.context.startAbility(want); })2、onCreate()或者onNewWant()生命周期获取、并用AppStorage存储
interface WantParamType { userId: number, userName:string } export default class MiniProgramAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { const userId = want.parameters?.userId const userName = want.parameters?.userName // console.log('qf ', userId, userName) AppStorage.setOrCreate('userId', userId) AppStorage.setOrCreate('userName', userName) hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); } 3、新拉起的UIAbility任务重通过@StroageProp修饰符获取
@Entry @Component struct MiniProgram { @StorageProp('userName') userName:string = '' @StorageProp('userId') userId:number = 0 build() { Column() { Text('微信小程序 ' + this.userName + this.userId).fontSize(50) } } }一些实战场景
启动应用内的UIAbility
启动应用内的UIAbility并获取返回结果
启动其他应用的UIAbility
启动其他应用的UIAbility并获取返回结果
启动UIAbility的指定页面
应用进程线程
进程
系统的进程模型如下图所示。
应用中(同一Bundle名称)的所有UIAbility、ServiceExtensionAbility和DataShareExtensionAbility均是运行在同一个独立进程(主进程)中,如下图中绿色部分的“Main Process”。
应用中(同一Bundle名称)的所有同一类型ExtensionAbility(除ServiceExtensionAbility和DataShareExtensionAbility外)均是运行在一个独立进程中,如下图中蓝色部分的“FormExtensionAbility Process”、“InputMethodExtensionAbility Process”、其他ExtensionAbility Process。
WebView拥有独立的渲染进程,如下图中黄色部分的“Render Process”。
图1进程模型示意图
说明:
仅系统应用支持构建ServiceExtensionAbility和DataShareExtensionAbility。
执行hdc shell命令,进入设备的shell命令行。在shell命令行中,执行ps -ef命令,可以查看所有正在运行的进程信息。
在上述模型基础上,对于系统应用可以通过申请多进程权限(如下图所示),为指定HAP配置一个自定义进程名,该HAP中的UIAbility、DataShareExtensionAbility、ServiceExtensionAbility就会运行在自定义进程中。不同的HAP可以通过配置不同的进程名运行在不同进程中。
图2多进程示意图
基于当前的进程模型,针对应用间和应用内存在多个进程的情况,系统提供了进程间通信机制:
线程
Stage模型下的线程主要有如下三类:
主线程
执行UI绘制。
管理主线程的ArkTS引擎实例,使多个UIAbility组件能够运行在其之上。
管理其他线程的ArkTS引擎实例,例如使用TaskPool(任务池)创建任务或取消任务、启动和终止Worker线程。
分发交互事件。
处理应用代码的回调,包括事件处理和生命周期管理。
接收TaskPool以及Worker线程发送的消息。
TaskPool Worker线程
用于执行耗时操作,支持设置调度优先级、负载均衡等功能,推荐使用。
Worker线程
用于执行耗时操作,支持线程间通信。
TaskPool与Worker的运作机制、通信手段和使用方法可以参考TaskPool和Worker的对比。
FA模型与Stage模型区别
Stage模型与FA模型最大的区别在于:Stage模型中,多个应用组件共享同一个ArkTS引擎实例;而FA模型中,每个应用组件独享一个ArkTS引擎实例。因此在Stage模型中,应用组件之间可以方便的共享对象和状态,同时减少复杂应用运行对内存的占用。Stage模型作为主推的应用模型,开发者通过它能够更加便利地开发出分布式场景下的复杂应用。
可通过如下对比表格了解两种模型的整体概况。
表1FA模型与Stage模型差异概览
| 项目 | FA模型 | Stage模型 |
|---|---|---|
| 应用组件 | 1. 组件分类 | 1. 组件分类 |
| 进程模型 | 有两类进程:1. 主进程2. 渲染进程详细介绍请参见进程模型。 | 有三类进程:1. 主进程2. ExtensionAbility进程3. 渲染进程详细介绍请参见进程模型。 |
| 线程模型 | 1. ArkTS引擎实例的创建一个进程可以运行多个应用组件实例,每个应用组件实例运行在一个单独的ArkTS引擎实例中。2. 线程模型每个ArkTS引擎实例都在一个单独线程(非主线程)上创建,主线程没有ArkTS引擎实例。3. 进程内对象共享:不支持。详细介绍请参见线程模型。 | 1. ArkTS引擎实例的创建一个进程可以运行多个应用组件实例,所有应用组件实例共享一个ArkTS引擎实例。2. 线程模型ArkTS引擎实例在主线程上创建。3. 进程内对象共享:支持。详细介绍请参见线程模型。 |
| 应用配置文件 | 使用config.json描述应用信息、HAP信息和应用组件信息。详细介绍请参见应用配置文件概述(FA模型)。 | 使用app.json5描述应用信息,module.json5描述HAP信息、应用组件信息。详细介绍请参见应用配置文件概述(Stage模型) |
欢迎加入课程班级,考取鸿蒙认证:
https://developer.huawei.com/consumer/cn/training/classDetail/d43582bb30b34f548c16c127cb3be104?type=1?ha_source=hmosclass&ha_sourceId=89000248