HarmonyOS应用开发-Stage模型开发概述

基本概念

UI框架

HarmonyOS提供了一套UI开发框架,即方舟开发框架(ArkUI框架)。提供了应用UI开发所必需的能力:多种组件、布局计算、动画能力、UI交互、绘制。 方舟开发框架针对开发者提供了两种开发范式:

  • 基于ArkTS的声明式开发范式,使用ArkTS语言,适用于复杂度较大、团队合作度较高的程序;适用移动系统应用开发人员、系统应用开发人员。
  • 兼容JS的类Web开发范式,使用JS语言,适用于界面较为简单的程序应用和卡片;适用Web前端开发人员。

应用模型

应用模型是HarmonyOS为开发者提供的应用程序所需能来的抽象提炼,它提供了应用程序必备的组件和运行机制。开发者可以基于一套统一的模型进行应用开发,使应用开发更简单、高效。 现在主要使用Stage模型,在该模型中,由于提供了AbilityStage、WindowStage类作为应用组件和Windows窗口的"舞台"。

Stage模型

Stage模型概念图

Stage模型提供UIAbility和ExtensionAbility两种类型的组件,这两种组件都有具体的类承载,支持面向对象的开发方式。

界面组件(Ability

  • UIAbility 组件是包含UI界面的应用组件,主要用于和用户交互。像Android中的Activity。也有自己的生命周期,不同的是UIAbility的生命周期只包含创建/销毁/前台/后台等状态,与显示相关的状态通过WindowStage的事件暴露出来。
  • ExtensionAbility组件是一种面向特定场景的应用组件。一般都是使用**UIAbility,**等具体用到再说。

WindowStage

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

Context

Context及其派生类向开发者提供在运行期可以调用的各种能力。UIAbility组件和各种ExtensionAbility派生类都有各自不同的Context类,他们都继承自基类Context,但是各自又根据所属组件,提供不同的能力。 目前我理解同Android中的Context上下文,后面再看。

AbilityStage

每个Entry类型或者Feature类型的HAP在运行期都有一个AbilityStage类实例,当HAP中的代码首次被加载到进程中的时候,系统会先创建AbilityStage实例。每个在该HAP中定义的UIAbility类,在实例化后都会与该实例产生关联。开发者可以使用AbilityStage获取该HAP中UIAbility实例的运行时信息。

Stage模型开发流程

作为开发者,在基于Stage模型进行开发应用时,需要学习了解如下流程:

  • 应用组件开发
    • 应用、组件级配置
    • UIAbility组件等其他组件
    • AbilityStage
    • 上下文Context
  • 了解进程模型
    • 进程模型和进程间通信方式
  • 了解线程模型
    • 线程模型和线程间通信方式
  • 应用配置文件
    • 配置文件中各个配置项

配置文件

配置文件简述

在应用开发过程中,需要对应用进行配置,如应用名称、应用包名、应用图标等设置。在HarmonyOS应用中分为2个层面的配置:

  • 应用层面,应用的图标、应用名称。在设置应用中(应用管理)中使用。其在app.json5配置文件中。
  • 入口页面层面,入口页面的图标、入口名称。在应用安装完成后在设备桌面上显示。其在module.json5配置文件中。**入口图标是以UIAbility为粒度,支持同一个应用存在多个入口图标和标签,点击后进入对应的UIAbility界面。**这个和Android不一样,Android应用只有一个入口。

应用级配置

在工程的AppScope目录下的app.json5配置文件中配置。 一般需要关注如下配置:

  • bundleName,包名,标识应用的唯一性。同Android上的packageId
  • icon,应用图标
  • label,应用标签(应用名称)
  • versionCode,应用版本号

app.json5配置示例:

typescript 复制代码
{
  "app": {
    "bundleName": "com.example.myapplication",
    "vendor": "example",
    "versionCode": 1000000,
    "versionName": "1.0.0",
    "icon": "$media:app_icon",
    "label": "$string:app_name"
  }
}

入口页面级配置

入口图标和入口标签(入口名称)会显示在桌面上。入口页面级配置在module.json5配置文件中配置。

需要关注如下配置:

  • abilities下的icon,入口图标
  • abilities下的label,入口标签(入口名称)

module.json5配置文件示例:

typescript 复制代码
{
  "module": {
    "name": "entry",
    "type": "entry",
    "description": "$string:module_desc",
    "mainElement": "EntryAbility",
    "deviceTypes": [
      "phone",
      "tablet"
    ],
    "deliveryWithInstall": true,
    "installationFree": false,
    "pages": "$profile:main_pages",
    "abilities": [
      {
        // UIAbility组件的名称
        "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",
        "exported": true,
        "skills": [
          {
            "entities": [
              "entity.system.home"
            ],
            "actions": [
              "action.system.home"
            ]
          }
        ]
      }
    ]
  }
}

UIAbility组件

UIAbility组件是一种包含UI界面的应用组件,主要用于和用户交互。 具体代码示例: EntryAbility.ets

typescript 复制代码
import UIAbility from '@ohos.app.ability.UIAbility';
import hilog from '@ohos.hilog';
import window from '@ohos.window';

export default class EntryAbility extends UIAbility {
  onCreate(want, launchParam) {
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
  }

  onDestroy() {
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
  }

  onWindowStageCreate(windowStage: window.WindowStage) {
    // Main window is created, set main page for this ability
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');

    windowStage.loadContent('pages/Index', (err, data) => {
      if (err.code) {
        hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
        return;
      }
      hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
    });
  }

  onWindowStageDestroy() {
    // Main window is destroyed, release UI related resources
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
  }

  onForeground() {
    // Ability has brought to foreground
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
  }

  onBackground() {
    // Ability has back to background
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
  }
}

UIAbility的生命周期

UIAbility的生命周期包括Create、Foreground、Background、Destroy四个状态,如下图所示:

WindowStageCreate和WindowStageDestroy状态

UIAbility实例创建完成之后,在进入Foreground之前,系统会创建一个WindowStage。WindowStage创建完成后会进入onWindowStageCreate()回调,可以在该回调中设置UI界面加载、设置WindowStage的事件订阅。

UIAbility组件启动模式

UIAbility的启动模式是指UIAbility实例在启动时的不同呈现状态。针对不同的业务场景,系统提供了三种启动模式:

在module.json5配置文件中的"launchType"字段配置:

typescript 复制代码
{
  "module": {
    // ...
    "abilities": [
      {
        // 设置启动模式
        "launchType": "singleton",
        // ...
      }
    ]
  }
}

指定UIAbility的启动页面

应用中的UIAbility在启动过程中,需要指定启动页面,否则应用启动后会因为没有默认加载页面而导致白屏。可以在UIAbility的onWindowStageCreate()生命周期回调中,通过WindowStage对象的loadContent()方法设置启动页面。

typescript 复制代码
import UIAbility from '@ohos.app.ability.UIAbility';
import hilog from '@ohos.hilog';
import window from '@ohos.window';

export default class EntryAbility extends UIAbility {
  //...

  onWindowStageCreate(windowStage: window.WindowStage) {
    // Main window is created, set main page for this ability
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');

    windowStage.loadContent('pages/Index', (err, data) => {
      if (err.code) {
        hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
        return;
      }
      hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
    });
  }
  //...
}

获取UIAbility的上下文信息

通过UIAbilityContext可以获取UIAbility的相关配置信息,如包代码路径、Bundle名称、Ability名称和应用程序需要的环境状态等属性信息,以及可以获取操作UIAbility实例的方法(如startAbility()、connectServiceExtensionAbility()、terminateSelf()等)

在UIAbility中可以通过this.context获取UIAbility实例的上下文信息。

typescript 复制代码
import UIAbility from '@ohos.app.ability.UIAbility';

export default class EntryAbility extends UIAbility {
    onCreate(want, launchParam) {
        // 获取UIAbility实例的上下文
        let context = this.context;

        // ...
    }
}

在页面中获取UIAbility实例的上下文信息,包括导入依赖资源context模块和在组件中定义一个context变量两个部分。

typescript 复制代码
import common from '@ohos.app.ability.common';

@Entry
@Component
struct Index {
  private context = getContext(this) as common.UIAbilityContext;

  startAbilityTest() {
    let want = {
      // Want参数信息
    };
    this.context.startAbility(want);
  }

  // 页面展示
  build() {
    // ...
  }
}
相关推荐
SameX6 小时前
HarmonyOS Next 安全生态构建与展望
前端·harmonyos
SameX6 小时前
HarmonyOS Next 打造智能家居安全系统实战
harmonyos
Random_index13 小时前
#Uniapp篇:支持纯血鸿蒙&发布&适配&UIUI
uni-app·harmonyos
鸿蒙自习室17 小时前
鸿蒙多线程开发——线程间数据通信对象02
ui·harmonyos·鸿蒙
SuperHeroWu719 小时前
【HarmonyOS】鸿蒙应用接入微博分享
华为·harmonyos·鸿蒙·微博·微博分享·微博sdk集成·sdk集成
zhangjr05751 天前
【HarmonyOS Next】鸿蒙实用装饰器一览(一)
前端·harmonyos·arkts
诗歌难吟4641 天前
初识ArkUI
harmonyos
SameX1 天前
HarmonyOS Next 设备安全特性深度剖析学习
harmonyos
郭梧悠1 天前
HarmonyOS(57) UI性能优化
ui·性能优化·harmonyos
郝晨妤2 天前
鸿蒙原生应用开发元服务 元服务是什么?和App的关系?(保姆级步骤)
android·ios·华为od·华为·华为云·harmonyos·鸿蒙