头图

在做Android开发时我们知道有四大组件,在HarmonyOS Next开发中最上来看到的是Ability,到底什么是Ability呢?希望通过本文的探索我们彻底搞懂它。

HarmonyOS中基础的页面元素是带Entry注释的Page,那么Page和Ability的关系是什么呢?通过下面Stage模型概念图我们可以了解一个轮廓:
image.png

  • 应用上架应用市场最终以App形式提交,App可以包含一个或者多个HAP;
  • App在运行期会对应一个Application,一个Application会持有一个ApplicationContext;
  • 一个HAP在运行期对应一个AbilityStage,一个AbilityStage持有一个AbilityStageContext,同时一个AbilityStage可以持有多个UIAbility,多个ExtensionAbility;
  • 一个UIAbility可以持有一个WindowStage,一个WindowStage持有一个WIndow,一个WIndow持有多个ArkUI Page;
  • UIAbility 持有一个UIAbilityContext。

基础概念介绍

AbilityStage

AbilityStage是HAP的运行时类。AbilityStage类提供在HAP加载的时候,通知开发者,可以在此进行该HAP的初始化(如资源预加载,线程创建等)能力。

AbilityStage是一个Module级别的组件容器,应用的HAP在首次加载时会创建一个AbilityStage实例,可以对该Module进行初始化等操作。AbilityStage与Module一一对应,即一个Module拥有一个AbilityStage。

DevEco Studio默认工程中未自动生成AbilityStage,如需要使用AbilityStage的能力,可以手动新建一个AbilityStage文件,具体步骤如下。

  1. 在工程Module对应的ets目录下,右键选择“New > Directory”,新建一个目录并命名为myabilitystage。
  2. 在myabilitystage目录,右键选择“New > ArkTS File”,新建一个文件并命名为MyAbilityStage.ets。
  3. 打开MyAbilityStage.ets文件,导入AbilityStage的依赖包,自定义类继承AbilityStage并加上需要的生命周期回调,示例中增加了一个onCreate()生命周期回调。

    import { AbilityStage } from '@kit.AbilityKit';
    
    class MyAbilityStage extends AbilityStage {
     //当应用创建时调用。
     onCreate() {
         console.log('MyAbilityStage.onCreate is called');
     }
     //启动一个specified ability时触发的事件
     onAcceptWant(want: Want) {
         console.log('MyAbilityStage.onAcceptWant called');
         return 'com.example.test';
     }
     //在指定进程中启动UIAbility时回调。
     onNewProcessRequest(want: Want) {
         console.log('MyAbilityStage.onNewProcessRequest called');
         return 'com.example.test';
     }
    
     //环境变化通知接口,发生全局配置变更时回调。
     onConfigurationUpdate(config: Configuration) {
         console.log(`onConfigurationUpdate, language: ${config.language}`);
     }
     //当系统已决定调整内存时调用。例如,当该功能在后台运行时,没有足够的内存来运行尽可能多的后台进程时可以使用。
     onMemoryLevel(level: AbilityConstant.MemoryLevel) {
         console.log(`onMemoryLevel, level: ${JSON.stringify(level)}`);
       }
     //当应用销毁时调用, 此方法将在正常的调度生命周期中调用, 当应用程序异常退出或被终止时,将不会调用此方法。
    onDestroy() {
         console.log('MyAbilityStage.onDestroy is called');
    }
    }
  4. 在module.json5配置文件中,通过配置 srcEntry 参数来指定模块对应的代码路径,以作为HAP加载的入口。

    {
      "module": {
     "name": "entry",
     "type": "entry",
     "srcEntry": "./ets/myabilitystage/MyAbilityStage.ets",
     // ...
      }
    }

UIAbility

UIAbility是包含UI界面的应用组件,继承自Ability,提供组件创建、销毁、前后台切换等生命周期回调,同时也具备组件协同的能力,组件协同主要提供如下常用功能:

  • Caller:由startAbilityByCall接口返回,CallerAbility(调用者)可使用Caller与CalleeAbility(被调用者)进行通信。
  • Callee:UIAbility的内部对象,CalleeAbility(被调用者)可以通过Callee与Caller进行通信。
    各类Ability的继承关系如下图所示:
    image.png

UIAbility组件是一种包含UI的应用组件,主要用于和用户交互。
UIAbility的设计理念:

  1. 原生支持应用组件级的跨端迁移和多端协同。
  2. 支持多设备和多窗口形态。

UIAbility划分原则与建议:
UIAbility组件是系统调度的基本单元,为应用提供绘制界面的窗口。一个应用可以包含一个或多个UIAbility组件。例如,在支付应用中,可以将入口功能和收付款功能分别配置为独立的UIAbility。
每一个UIAbility组件实例都会在最近任务列表中显示一个对应的任务。
对于开发者而言,可以根据具体场景选择单个还是多个UIAbility,划分建议如下:

  • 如果开发者希望在任务视图中看到一个任务,建议使用“一个UIAbility+多个页面”的方式,可以避免不必要的资源加载。
  • 如果开发者希望在任务视图中看到多个任务,或者需要同时开启多个窗口,建议使用多个UIAbility实现不同的功能。
    例如,即时通讯类应用中的消息列表与音视频通话采用不同的UIAbility进行开发,既可以方便地切换任务窗口,又可以实现应用的两个任务窗口在一个屏幕上分屏显示。

为使应用能够正常使用UIAbility,需要在module.json5配置文件的abilities标签中声明UIAbility的名称、入口、标签等相关信息。

{
  "module": {
    // ...
    "abilities": [
      {
        "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组件启动页面背景颜色资源文件的索引
        // ...
      }
    ]
  }
}

WindowStage

窗口管理器,管理各个基本窗口单元。支持方法:
image.png

Window

当前窗口实例,窗口管理器管理的基本单元。

image.png

HAP

HAP(Harmony Ability Package)是应用安装和运行的基本单元。HAP包是由代码、资源、第三方库、配置文件等打包生成的模块包,其主要分为两种类型:entry和feature。

  • entry:应用的主模块,作为应用的入口,提供了应用的基础功能。
  • feature:应用的动态特性模块,作为应用能力的扩展,可以根据用户的需求和设备类型进行选择性安装。

应用程序包可以只包含一个基础的entry包,也可以包含一个基础的entry包和多个功能性的feature包。

HAP有两种使用方式:

  • 单HAP场景:如果只包含UIAbility组件,无需使用ExtensionAbility组件,优先采用单HAP(即一个entry包)来实现应用开发。虽然一个HAP中可以包含一个或多个UIAbility组件,为了避免不必要的资源加载,推荐采用“一个UIAbility+多个页面”的方式。
  • 多HAP场景:如果应用的功能比较复杂,需要使用ExtensionAbility组件,可以采用多HAP(即一个entry包+多个feature包)来实现应用开发,每个HAP中包含一个UIAbility组件或者一个ExtensionAbility组件。在这种场景下,可能会存在多个HAP引用相同的库文件,导致重复打包的问题。

开发态与编译态的工程结构视图
image.png

每个应用中至少包含一个.hap文件,可能包含若干个.hsp文件、也可能不含,一个应用中的所有.hap与.hsp文件合在一起称为Bundle,其对应的bundleName是应用的唯一标识(详见app.json5配置文件中的bundleName标签)。

当应用发布上架到应用市场时,需要将Bundle打包为一个.app后缀的文件用于上架,这个.app文件称为App Pack(Application Package),与此同时,DevEco Studio工具自动会生成一个pack.info文件。pack.info文件描述了App Pack中每个HAP和HSP的属性,包含APP中的bundleName和versionCode信息、以及Module中的name、type和abilities等信息。

编译发布与上架部署流程图
image.png

可以理解为HAP是安装到设备的基本单元,App只是上架应用市场时的一个包集合,最终下发安装时还是以HAP为单位。

参考

  1. Stage模型开发概述
  2. AbilityStage组件容器
  3. @ohos.app.ability.AbilityStage (AbilityStage)
  4. Stage模型应用程序包结构
  5. HAP
  6. @ohos.app.ability.UIAbility (UIAbility)
  7. @ohos.app.ability.Ability (Ability基类)
  8. 管理应用窗口(Stage模型)
  9. @ohos.window (窗口)
  10. UIAbility组件概述
  11. ExtensionAbility组件

总结

Ability提供系统配置更新回调和系统内存调整回调,其中UIAbility是一种包含UI的应用组件,主要用于和用户交互,一个UIAbility对应一个Window,可以包含多个Page,一个UIAbility对应一个最近任务列表中的一个任务。


轻口味
35.2k 声望5.3k 粉丝

移动端十年老人,主要做IM、音视频、AI方向,目前在做鸿蒙化适配,欢迎这些方向的同学交流:wodekouwei