HarmonyOS NEXT:应用程序框架进阶

news/2025/2/5 16:26:30 标签: harmonyos, 华为

基本概念

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

ExtensionAbility组建:基于特定场景,如服务卡片、输入法等提供的应用组件,每一个具体场景对应一个ExtensionAbilityType,开发者只能使用系统已定义的类型。

HAP:应用安装的基本单位

AbilityStage:Module级别的组件容器,与HAP是一一对应的关系。

UIAbility组件概述

UIAbility组件是系统调度的基本单元,为应用提供绘制界面的窗口。一个应用可以包含一个或多个UIAbility组件。例如,在支付应用中,可以将入口功能和收付款功能分别配置为独立的UIAbility。

每一个UIAbility组件实例都会在最近任务列表中显示一个对应的任务。

  • 如果开发者希望在任务视图中看到一个任务,建议使用“一个UIAbility+多个页面”的方式,可以避免不必要的资源加载。

  • 如果开发者希望在任务视图中看到多个任务,或者需要同时开启多个窗口,建议使用多个UIAbility实现不同的功能。

例如,即时通讯类应用中的消息列表与音视频通话采用不同的UIAbility进行开发,既可以方便地切换任务窗口,又可以实现应用的两个任务窗口在一个屏幕上分屏显示。

UIAbility组件的基本用法

指定UIAbility的启动页面以及获取UIAbility的上下文UIAbilityContext。

1. 指定UIAbility的启动页面

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

import { UIAbility } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';

export default class EntryAbility extends UIAbility {
  onWindowStageCreate(windowStage: window.WindowStage): void {
    // Main window is created, set main page for this ability
    windowStage.loadContent('pages/Index', (err, data) => {
      // ...
    });
  }
  // ...
}

2. 获取UIAbility的上下文信息

UIAbility类拥有自身的上下文信息,该信息为UIAbilityContext类的实例,UIAbilityContext类拥有abilityInfo、currentHapModuleInfo等属性。通过UIAbilityContext可以获取UIAbility的相关配置信息,如包代码路径、Bundle名称、Ability名称和应用程序需要的环境状态等属性信息。

import { UIAbility, AbilityConstant, Want } from '@kit.AbilityKit';

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

在页面中获取Context信息:1.导入common模块 2. 定义context变量

import { common, Want } from '@kit.AbilityKit';

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

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

  // 页面展示
  build() {
    // ...
  }
}

 可以调用context方法来终结当前UIAbility实例。

import { common } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';

@Entry
@Component
struct Page_UIAbilityComponentsBasicUsage {
  // 页面展示
  build() {
    Column() {
      //...
      Button('FuncAbilityB')
        .onClick(() => {
          let context = getContext(this) as common.UIAbilityContext;
          try {
            context.terminateSelf((err: BusinessError) => {
              if (err.code) {
                // 处理业务逻辑错误
                console.error(`terminateSelf failed, code is ${err.code}, message is ${err.message}`);
                return;
              }
              // 执行正常业务
              console.info('terminateSelf succeed');
            });
          } catch (err) {
            // 捕获同步的参数错误
            let code = (err as BusinessError).code;
            let message = (err as BusinessError).message;
            console.error(`terminateSelf failed, code is ${code}, message is ${message}`);
          }
        })
    }
  }
}
什么是Context?

Context模块继承自BaseContext,提供了ability或application的上下文的能力,包括访问特定应用程序的资源等。它就像是 UIAbility 与其他系统资源以及应用内部信息沟通的桥梁。

其提供了应用的一些基础信息,例如resourceManager(资源管理)、applicationInfo(当前应用信息)、dir(应用文件路径)、area(文件分区)等,以及应用的一些基本方法,例如createBundleContext()、getApplicationContext()等。

Context的典型使用场景

获取应用文件路径https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/application-context-stage-V5#获取应用文件路径

UIAbility组件与UI的数据同步

开发时,多个页面或多个UIAbility中,有一些需要共享的UI数据,有多种方式可以实现。

使用AppStorage/LocalStorage进行数据同步

ArkUI提供了AppStorage和LocalStorage两种应用级别的状态管理方案,可用于实现应用级别和UIAbility级别的数据同步。使用这些方案可以方便地管理应用状态,提高应用性能和用户体验。

其中,AppStorage是一个全局的状态管理器,适用于多个UIAbility共享同一状态数据的情况;

而LocalStorage则是一个局部的状态管理器,适用于单个UIAbility内部使用的状态数据。

LocalStorage:页面级UI状态存储

LocalStorage是页面级的UI状态存储,通过@Entry装饰器接收的参数可以在页面内共享同一个LocalStorage实例。LocalStorage支持UIAbility实例内多个页面间状态共享。

1. 创建 LocalStorage 实例

在页面入口或组件中创建 LocalStorage 实例,并初始化属性。

let storage: LocalStorage = new LocalStorage();
storage.setOrCreate('PropA', 47);

2. 使用 @LocalStorageLink 装饰器绑定属性

在 UI 组件中使用 @LocalStorageLink 装饰器,与 LocalStorage 中的属性建立双向数据同步。

@Component
struct Index {
  @LocalStorageLink('PropA') localStorageLink: number = 1;

  build() {
    Column() {
      Text(`From LocalStorage ${this.localStorageLink}`)
        .onClick(() => {
          this.localStorageLink += 1;
        });
    }
  }
}

3. 页面内同步

LocalStorage 的页面级特性使得同一页面内的组件可以共享状态。当一个组件修改状态时,页面内的其他组件会自动同步更新。

@Component
struct Child {
  @LocalStorageLink('PropA') childLink: number = 1;

  build() {
    Column() {
      Text(`From LocalStorage in Child ${this.childLink}`);
    }
  }
}

AppStorage:应用全局的UI状态存储

AppStorage是应用全局的UI状态存储,是和应用的进程绑定的,由UI框架在应用程序启动时创建,为应用程序UI状态属性提供中央存储。

1. 设置 AppStorage 属性

AppStorage 是单例,可以通过静态方法 AppStorage.setOrCreate(key, value) 设置或创建属性。

AppStorage.setOrCreate('PropA', 47);

2. 使用 @StorageLink 装饰器绑定属性

在 UI 组件中使用 @StorageLink 装饰器,与 AppStorage 中的属性建立双向数据同步。

@Component
struct Index {
  @StorageLink('PropA') storageLink: number = 1;

  build() {
    Column() {
      Text(`From AppStorage ${this.storageLink}`)
        .onClick(() => {
          this.storageLink += 1;
        });
    }
  }
}

3. 多页面同步

AppStorage 的全局特性使得不同页面可以共享状态。当一个页面修改状态时,其他页面会自动同步更新。

@Component
struct OtherPage {
  @StorageLink('PropA') storageLink: number = 1;

  build() {
    Column() {
      Text(`From AppStorage in OtherPage ${this.storageLink}`);
    }
  }
}
  • AppStorage:适用于应用全局状态共享,如用户登录状态、主题模式等,这些状态需要在多个页面或 Ability 之间共享。

  • LocalStorage:适用于页面内部状态共享,如表单数据、页面切换状态等,这些状态不需要跨页面或 Ability 。

使用Stage模型进行项目构建

DevEco Studio创建出的默认工程仅包含一个的entry类型的模块,如果直接平级目录进行模块管理,工程逻辑结构较混乱且模块间的依赖关系不够清晰,不利于多人开发和维护。

开发过程推荐使用三层架构

三层工程结构如下:

  • commons(公共能力层):用于存放公共基础能力集合(如工具库、公共配置等)。commons层可编译成一个或多个HAR包或HSP包,只可以被products和features依赖,不可以反向依赖。

  • features(基础特性层):用于存放基础特性集合(如应用中相对独立的各个功能的UI及业务逻辑实现等)。各个feature高内聚、低耦合、可定制,供产品灵活部署。不需要单独部署的feature通常编译为HAR包或HSP包,供products或其它feature使用。需要单独部署的feature通常编译为Feature类型的HAP包,和products下Entry类型的HAP包进行组合部署。features层可以横向调用及依赖common层,同时可以被products层不同设备形态的HAP所依赖,但是不能反向依赖products层。

  • products(产品定制层):用于针对不同设备形态进行功能和特性集成。products层各个子目录各自编译为一个Entry类型的HAP包,作为应用主入口。products层不可以横向调用。

三层架构配置方法华为终端Codelabs提供技术专家指导、教程和动手编码体验,在这里你能了解到华为各项最新的尖端技术,并与华为技术专家&全国各地的coder分享知识与见解,一起探索代码的独特魅力。https://developer.huawei.com/consumer/cn/codelabsPortal/carddetails/tutorials_Next-BasicArchitectureDesignPart2

HAP

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

HAPhttps://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V14/hap-package-V14

HAR

HAR(Harmony Archive)是静态共享包,可以包含代码、C++库、资源和配置文件。通过HAR可以实现多个模块或多个工程共享ArkUI组件、资源等相关代码。HAR不同于HAP,不能独立安装运行在设备上,只能作为应用模块的依赖项被引用。

开发静态共享包https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/ide-har-V5

HSP

DevEco Studio支持开发动态共享包HSP(Harmony Shared Package)。在应用/元服务开发过程中部分功能按需动态下载,或开发元服务场景时需要分包加载,可使用HSP实现相应功能。当有多个安装包需要资源共享时,也可利用HSP减少公共资源和代码重复打包。 

开发动态共享包https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/ide-hsp-V5

导出ArkUI组件

创建好HSP和HAR包后,需要在包内导出相关组件

声明组件

// library/src/main/ets/components/mainpage/MainPage.ets
@Component
export struct MainPage {
  @State message: string = 'HAR MainPage';

  build() {
    Column() {
      Row() {
        Text(this.message)
          .fontSize(32)
          .fontWeight(FontWeight.Bold)
      }
      .margin({ top: '32px' })
      .height(56)
      .width('624px')

      Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center, alignContent: FlexAlign.Center }) {
        Column() {
          Image($r('app.media.pic_empty')).width('33%')
          Text($r('app.string.empty'))
            .fontSize(14)
            .fontColor($r('app.color.text_color'))
        }
      }.width('100%')
      .height('90%')
    }
    .width('100%')
    .height('100%')
    .backgroundColor($r('app.color.page_background'))
  }
}

HAR对外暴露的接口,在Index.ets导出文件中声明如下所示:

// library/Index.ets
export { MainPage } from './src/main/ets/components/mainpage/MainPage';

 随后MainPage组件可以被其他Module引用。

引用共享包(HAR、HSP)

通过如下两种方式设置三方包依赖信息:

  • 方式一:在Terminal窗口中,切换到需要引入三方包的模块,如entry模块,执行如下命令安装三方包,DevEco Studio会自动在该模块的oh-package.json5中自动添加三方包依赖。
cd path/to/your/project/entry
ohpm install @ohos/lottie
  • 方式二:在需要引入三方包的模块的oh-package.json5中设置三方包依赖,配置示例如下:
"dependencies": {
  "@ohos/lottie": "^2.0.0"
}
  • 依赖设置完成后,需要执行ohpm install命令安装依赖包,依赖包会安装到该模块的oh_modules目录下。
ohpm install

引用本地模块源码(该本地模块必须与宿主模块归属于同一个工程),如entry模块需要依赖foo模块的源码,有如下两种方式:

  • 方式一:在Terminal窗口中,切换到需要引入本地模块源码的模块,即entry模块下,执行如下命令进行安装,并会在该模块下的oh-package.json5中自动添加依赖。
cd path/to/your/project/entry
ohpm install path/to/foo
  • 方式二:在需要引入本地模块源码的模块的oh-package.json5中设置源码依赖项,即entry模块的oh-package.json5中,添加如下配置:
"dependencies": {
  "foo": "file:path/to/foo" // 此处也可以是以当前oh-package.json5所在目录为起点的相对路径
}
  • 依赖设置完成后,需要执行ohpm install命令安装依赖包,模块foo的源码会安装在entry模块的oh_modules目录下。 
ohpm install


http://www.niftyadmin.cn/n/5842323.html

相关文章

C++ Primer 多维数组

欢迎阅读我的 【CPrimer】专栏 专栏简介:本专栏主要面向C初学者,解释C的一些基本概念和基础语言特性,涉及C标准库的用法,面向对象特性,泛型特性高级用法。通过使用标准库中定义的抽象设施,使你更加适应高级…

Swift 进阶:Observation 框架中可观察(@Observable)对象的高级操作(上)

概述 在 WWDC 24 中苹果推出了全新的 Observation 框架,借助于它我们可以更加细粒度的监听可观察(@Observable)对象 。同时,SwiftUI 自身也与时偕行开始全面支持 @Observable 对象的“嵌入”。 然而在这里,我们却另辟蹊径来介绍 @Observable 对象另外一些“鲜为人知”的故…

项目中常用中间件有哪些?分别起什么作用?

在项目开发中,常用的中间件包括消息中间件、缓存中间件、数据库中间件等,以下是一些常见的中间件及其作用: 消息中间件 Kafka:一般用于处理大规模的消息数据,具有高吞吐量、低延迟的特点,适用于日志收集、…

mysql操作语句与事务

数据库设计范式 数据库设计的三大范式 ‌第一范式(1NF)‌:要求数据库表的每一列都是不可分割的原子数据项,即列中的每个值都应该是单一的、不可分割的实体。例如,如果一个表中的“地址”列包含了省、市、区等多个信息…

windows环境下如何在PyCharm中安装软件包

windows环境下如何在pyCharm中安装wxPython软件包 在windows环境中,安装软件包可以使用 终端 的方式,在IDE下方的终端中执行pip install wxPython进行安装,安装完毕之后,使用pip show wxPython检查也符合预期。 但是在代码文件中导…

【怎么用系列】短视频戒除—1—对推荐算法进行干扰

如今推荐算法已经渗透到人们生活的方方面面,尤其是抖音等短视频核心就是推荐算法。 【短视频的危害】 1> 会让人变笨,慢慢让人丧失注意力与专注力 2> 让人丧失阅读长文的能力 3> 让人沉浸在一个又一个快感与嗨点当中。当我们刷短视频时&#x…

介绍一下Mybatis的底层原理(包括一二级缓存)

表面上我们的就是Sql语句和我们的java对象进行映射,然后Mapper代理然后调用方法来操作数据库 底层的话我们就涉及到Sqlsession和Configuration 首先说一下SqlSession, 它可以被视为与数据库交互的一个会话,用于执行 SQL 语句(Ex…

芝法酱学习笔记(2.6)——flink-cdc监听mysql binlog并同步数据至elastic-search和更新redis缓存

一、需求背景 在有的项目中,尤其是进销存类的saas软件,一开始为了快速把产品做出来,并没有考虑缓存问题。而这类软件,有着复杂的业务逻辑。如果想在原先的代码中,添加redis缓存,改动面将非常大&#xff0c…