鸿蒙NEXT —— Stage应用模型概述

278 阅读8分钟

一、应用模型构成要素

应用模型是系统为开发者提供的应用程序所需能力的抽象提炼,它提供了应用程序必备的组件和运行机制。有了应用模型,开发者可以基于一套统一的模型进行应用开发,使应用开发更简单、高效。

应用模型的构成要素包括:

  1. 应用组件:应用组件是应用的基本组成单位,是应用的运行入口。
  2. 应用进程模型:应用进程模型定义应用进程的创建和销毁方式,以及进程间的通信方式。
  3. 应用线程模型:应用进程内线程的创建和销毁方式、主线程和UI线程的创建方式、线程间的通信方式。
  4. 应用任务管理模型:应用任务管理模型定义任务(Mission)的创建和销毁方式,以及任务与组件间的关系。所谓任务,即用户使用一个应用组件实例的记录。
  5. 应用配置文件:包含应用配置信息、应用组件信息、权限信息、开发者自定义信息等。

这里不再对比 Stage 模型和 FA 模型,FA 模型鸿蒙不再主推,所以我们新入场的开发者只需要聚焦到 Stage 模型即可。Stage模型由于提供了AbilityStage、WindowStage等类作为应用组件和Window窗口的“舞台”,因此称这种应用模型为Stage模型。

更多相关知识可查看 应用模型的构成要素

二、应用程序包结构

在进行 Stage 模型开发之前,需要先了解下应用程序的整体结构,通过 DevEco Studio 新建一个工程:

  1. AppScope -> resources:全局资源,包含应用图标资源、应用名资源等。
  2. AppScope -> app.json5:全局配置信息,包含应用唯一包名、版本号、应用名、应用图标等。
  3. entry -> src/main/ets:包含entry 模块所有 ets 源码文件。
  4. entry -> src/main/resources:包含entry 模块所有资源文件。
  5. entry -> src/main/module.json5:entry 模块配置文件,包含支持的设备类型、应用组件声明、权限声明等。
  6. entry -> build-profile.json5:entry 模块编译构建配置文件,包含产品配置、混淆开关等。
  7. entry -> obfusication-rules.txt: entry 模块混淆规则文件。
  8. entry -> oh-package.json5:包含 entry 模块所有依赖库声明。
  9. build-profile.json5: 全局编译构建配置文件,包含应用签名信息、产品配置等。
  10. hvigorfile.ts:全局构建脚本,可以自定义编译构建逻辑。
  11. oh-package.json5:全局依赖库声明文件。

我们从安卓开发的视角上看,鸿蒙开发时应用程序包结构真的和安卓非常像。

  • 在鸿蒙中编译构建工具是 hvigor 对应安卓中的 gradle,并且 build-profile.json5 + oh-package.json5 基本等同于安卓中的 build.gradle,鸿蒙拆分出 oh-package.json5 估计是为了让结构更加清晰。
  • 模块的 module.json5 文件又是基本等同于安卓的 AndroidManifest.xml 文件,都是用来声明一些组件和权限的。

理解了上面的开发时应用程序包结构,我们再来看下编译后的应用程序包结构对比图:

可以看到编译产物主要做了两件事:

  • 整合资源,hap 包依赖的 har 包资源以及全局资源合并到自身的资源中,hsp 包合并全局资源。
  • 源码编译,hap 包以及依赖的 har 包的所有 ets 文件编译成 .abc 文件,hsp 包将自身 ets 文件编译成 .abc 文件。

这里可以看到一个工程可以包含多个 hap, har, hsp 包,我们看下这几个包到底是什么。

HAP

应用的功能模块,可以独立安装和运行,必须包含一个entry类型的HAP,可选包含一个或多个feature类型的HAP。

HAR

静态共享包,编译态复用。支持应用内共享,也可以发布后供其他应用使用。引用相同的HAR时,会造成多包间代码和资源的重复拷贝,从而导致应用包膨大。

HSP

动态共享包,运行时复用。当前仅支持应用内共享。同时引用同一个共享包时,采用HSP替代HAR,可以避免HAR造成的多包间代码和资源的重复拷贝,从而减小应用包大小。

包类型可以在 module.json5 内直观的看到:

更多知识可查看 应用程序包基础知识

三、Stage模型开发概述

在第一章已经描述过应用模型构成要素,Stage 模型也是遵从这样的要素构成。

应用组件

先来看一张概念图:

UIAbility组件:一种包含UI的应用组件,主要用于和用户交互。UIAbility组件的生命周期只包含创建/销毁/前台/后台等状态,与显示相关的状态通过WindowStage的事件暴露给开发者。如果你是一个安卓开发,你可以将其理解为Activity。

ExtensionAbility组件:一种面向特定场景的应用组件。开发者并不直接从ExtensionAbility组件派生,而是需要使用ExtensionAbility组件的派生类。目前ExtensionAbility组件有用于卡片场景的FormExtensionAbility,用于输入法场景的InputMethodExtensionAbility,用于闲时任务场景的WorkSchedulerExtensionAbility等多种派生类,这些派生类都是基于特定场景提供的。

WindowStage: 每个UIAbility实例都会与一个WindowStage类实例绑定,该类起到了应用进程内窗口管理器的作用。它包含一个主窗口。也就是说UIAbility实例通过WindowStage持有了一个主窗口,该主窗口为ArkUI提供了绘制区域。

Context: Context及其派生类向开发者提供在运行期可以调用的各种资源和能力。UIAbility组件和各种ExtensionAbility组件的派生类都有各自不同的Context类,他们都继承自基类Context,但是各自又根据所属组件,提供不同的能力。

AbilityStage: 每个Entry类型或者Feature类型的HAP在运行期都有一个AbilityStage类实例,当HAP中的代码首次被加载到进程中的时候,系统会先创建AbilityStage实例。

如果你是一个安卓开发者,到此为止都很好理解,HAP包中的组件基本可以和安卓中应用组件一一对应,如果你的应用是单HAP架构(相信大多数app会采用这种相对简单的架构),那么 AbilityStage 就是安卓中的 Application 的概念,你可以在应用启动的时候在 AbilityStage 内做初始化的事情。但是鸿蒙又支持多HAP包架构,即一个APP可以有多个HAP包,所以APP自己会有一个 Application 的概念并且有全局的 ApplicationContext 上下文是所有HAP包能共享的,当然应用只能有一个 entry 类型的HAP包(应用启动时执行 AbilityStage 初始化),其他HAP包只能是 feature类型,个人理解鸿蒙支持这种架构可能是为了应用的功能可以解耦、可插拔、快速复用等方面的考虑。

进程模型

  • 应用中(同一Bundle名称)的所有UIAbility、ServiceExtensionAbility和DataShareExtensionAbility均是运行在同一个独立进程(主进程)中,如下图中绿色部分的“Main Process”。
  • 应用中(同一Bundle名称)的所有同一类型ExtensionAbility(除ServiceExtensionAbility和DataShareExtensionAbility外)均是运行在一个独立进程中,如下图中蓝色部分的“FormExtensionAbility Process”、“InputMethodExtensionAbility Process”、其他ExtensionAbility Process。
  • WebView拥有独立的渲染进程,如下图中黄色部分的“Render Process”。

当然因为鸿蒙支持多HAP架构,你可以给HAP指定进程:

线程模型

Stage模型下的线程主要有如下三类:

  • 主线程
    • 执行UI绘制。
    • 管理主线程的ArkTS引擎实例,使多个UIAbility组件能够运行在其之上。
    • 管理其他线程的ArkTS引擎实例,例如使用TaskPool(任务池)创建任务或取消任务、启动和终止Worker线程。
    • 分发交互事件。
    • 处理应用代码的回调,包括事件处理和生命周期管理。
    • 接收TaskPool以及Worker线程发送的消息。
  • TaskPool Worker线程
    • 用于执行耗时操作,支持设置调度优先级、负载均衡等功能,推荐使用。
  • Worker线程
    • 用于执行耗时操作,支持线程间通信。

TaskPool其实就是一个管理线程的线程池,里面的线程就是Worker线程。我们在开发中尽量使用TaskPool就可以,会少很多线程创建/销毁/复用等操作。

应用任务管理模型

应用任务管理就是在使用手机时通过手势或按键唤起"最近任务"列表,我们可以移除某个任务使其不再后台存活。在安卓中往往一个进程会代表一个任务,但鸿蒙任务机制有点“怪”,使用一个应用组件实例就会有一个任务记录,所以如果我们从一个 UIAbility 跳转到另一个 UIAbility 这个时候我们这个应用就会有两个任务,一个应用可能在后台就有很多很多任务。官网建议一个功能尽量用一个UIAbility+多个page的方式开发。

应用配置文件

可参考第二章内容。

更多内容可参考 Stage模型开发指导

以上内容大多数摘抄自官网文档并结合自身理解,主要用于整合 Stage 应用模型相关的知识点,便于自身以及读者更快的了解什么是 Stage 模型。

参考资料:

应用模型的构成要素

Stage模型开发指导

应用程序包基础知识