当前位置: 首页 > article >正文

HarmonyOS NEXT:应用程序框架进阶

基本概念

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.kler.cn/a/533596.html

相关文章:

  • gesp(C++六级)(13)洛谷:P11375:[GESP202412 六级] 树上游走
  • 解决threeJS加载obj gltf和glb模型后颜色太暗的方法
  • Docker Hub 镜像 Pull 失败的解决方案
  • MySQL 缓存机制与架构解析
  • 【网络编程】Java高并发IO模型深度指南:BIO、NIO、AIO核心解析与实战选型
  • 基序和纯度分数的计算
  • Android Studio:Application 和 Activity的区别
  • C语言打印输出星号图形(三角形、菱形、漏斗)
  • UE虚幻引擎No Google Play Store Key:No OBB found报错如何处理
  • Android12 MTK apk安装时默认授权
  • Python----Python高级(并发编程:进程Process,多进程,进程间通信,进程同步,进程池)
  • 力扣-哈希表-349 两个数组的交集
  • 异步程序设计方式
  • 使用 Deno 构建现代 Web 应用:探索新一代 JavaScript 运行时的魅力
  • 【Golang学习之旅】Go 语言数据类型详解(string、slice、map等)
  • Typora免费使用
  • GB/T 44721-2024 与 L3 自动驾驶:自动驾驶新时代的基石与指引
  • 30、Flink中操作已经配置好的远程文件系统
  • PyTorch Geometric(PyG)机器学习实战
  • deepseek设计硬件电路之设计一个pA级电流测量电路
  • Android 常用命令和工具解析之Battery Historian
  • 基于HTML生成网页有什么优势
  • Java—不可变集合
  • 最新黑马商城运行问题解决
  • 优化数据库结构
  • 服务器安装了esxi,通过esxi创建了N个虚拟机,如何实现类似于阿里云或者腾讯云的类似的云端管理虚拟机监控虚拟机的系统,要求开源,中文界面