7. Harmony 应用框架

 

Posted by     DH on December 2, 2024

UIAbility简介

概述

(1)UIAbility是一个组件,包含了UI,为用户提供显示和交互的组件;

(2)是应用调度的最小基本单元,为应用提供绘制UI的窗口;

(3)一个UIAbility可以包含多个页面,并且在页面之间进行跳转;

(4)每一个UIAbility都对应于鸿蒙系统的一个任务;

应用、模块(module)、UIAbility、page之间的关系:

一个应用,可以包含多个module,一个module可以包含多个UIAbility,一个UIAbility可以跳转多个page(最多32个);

配置

对于UIAbility的配置文件,位于当前module下的位置如上图所示。

UIAbility内部页面跳转

跳转

使用router进行跳转,并且可传参

页面1:

import { router } from '@kit.ArkUI';

@Entry
@Component
struct Index {
  @State message: string = '这是主页';

  build() {
    Column() {
      Text(this.message)
        .id('HelloWorld')
        .fontSize(50)
        .fontWeight(FontWeight.Bold)
        .alignRules({
          center: { anchor: '__container__', align: VerticalAlign.Center },
          middle: { anchor: '__container__', align: HorizontalAlign.Center }
        })

      Button("跳转").onClick(()=>{
          router.pushUrl({
            url:'pages/Page1',
            params:{
              name:"参数传递",
              age:11
            }
          })
      })
    }
    .height('100%')
    .width('100%')
  }
}

跳转时,通过params进行了参数传递,接收页面代码如下:

import { router } from '@kit.ArkUI';

@Component
@Entry
struct Page1{

  @State data:string = "";

  /**
   * 生命周期1:
   */
  aboutToAppear(): void {
    console.log("david-" + "1. aboutToAppear")
    let data  = router.getParams();
    if (data != undefined && data != null) {
      console.log("david-获取的参数 = " + JSON.stringify(data));
      this.data = JSON.stringify(data);
    }

  }

  /**
   * 生命周期2:
   */
  build() {
    Column(){
      Text("主页调过来的 = " + this.data);

    }
  }
  /**
   * 生命周期3:
   */
  onPageShow(): void {
    console.log("david-" + "3. onPageShow")
  }

  /**
   * 生命周期4:
   */
  onPageHide(): void {
    console.log("david-" + "4. onPageHide")
  }

  /**
   * 生命周期5
   */
  aboutToDisappear(): void {
    console.log("david-" + "5. aboutToDisappear")
  }

}

传参

page生命周期

页面生命周期如果所示:

这里要明确,页面就是指被@Enter修饰的类。

(1)aboutToAppear:生命周期1,主要用于完成页面初始化相关工作,例如数据请求;

(2)builde:进行UI构建;

(3)onPageShow:页面即将可见的时候,或者应用从后台来到前台时;

(4)onPageHide:页面即将不可见,按后退键、跳转到其他页面、应用退到后台,会触发该声明周期;

(5)aboutToDisPear:页面销毁时

UIAbility之间跳转

多UIAbility的使用场景

一般的中小型应用使用单UIAbility + 多Page的模式即可实现功能,但是存在一些场景使用多Ability:

(1)组件化开发:大型应用中,往往以功能来划分模块,每个模块有不同的UIAbility,例如淘宝的购物车和结账可分拆为不同的组件,拥有不同的UIAbility;

(2)多平台支持:某功能在手机、平板、穿戴设备的UI展示、交互不同,可使用多UIAbility作区分;

UIAbility的配置

UIAbility的配置文件位置如图所示,每当添加一个新的Ability就会自动添加相应的配置:

其中Skills标签标识UIAbility组件或者ExtensionAbility组件能够接收的Want的特征;

exported标识当前UIAbility组件是否可以被其他应用调用。

UIAbility的交互(跳转)

跳转使用上下文提供的方法startAbility,参数是一个Want的对象:


import common from '@ohos.app.ability.common'
import { Want } from '@kit.AbilityKit';

@Component
@Entry
struct FirstPage{
  build(){
    Column(){
      Button("跳转到第二个UIAbility").onClick(()=>{
        let context :common.UIAbilityContext =  getContext(this) as common.UIAbilityContext;
        let want:Want = {
          // 位于app.json5文件中
          bundleName: "com.example.harmony",
          // 要跳转的Ability
          abilityName: "SecondAbility",
          // 不填表示当前设备
          deviceId: "",
          parameters: {
            from:"FirstPage"
          },
          
          moduleName: "entry"
        };
        context.startAbility(want);
      })
    }
  }
}

这里跳转到SecondAbility之后,任务栈会有两个任务:

默认情况下,如果在第一个界面再次点击按钮调准到第二个界面,如果任务栈中存在,就直接跳转,如果不存在就重新创建第二个Ability。

如果想要每次都创建一个新的Ability,就需要设置module.json文件中的launchType,这样每次点击跳转到SecondAbility都会创建一个新的Ability,任务栈中会存在多个SecondAbility:

对于第二个Ability的参数接收,可以看到在onCreat函数中的入参want,就是上一个Ability传递过来的,从中可以获取对应的参数:

UIAbility生命周期

UIAbilty 的生命周期只有4个:

(1)onCreat: Ability创建时调用

(2)onForeground: 任务处于前台

(3)onBackground: 任务处于后台,一般是切到其他应用

(4)onDestroy: 任务销毁,一般是关闭应用,或应用被系统杀掉

需要注意的是,有两个不属于UIAbilty生命周期的函数:

image

(1)onWindowStageCreate:

image

调用时机位于onCreat和onForeground之间,主要在回调中通过loadContent()方法设置应用要加载的页面

(2)onWindowStageDestroy:

在UIAbility实例销毁之前,则会先进入onWindowStageDestroy()回调,可以在该回调中释放UI资源。

import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';

export default class SecondAbility extends UIAbility {
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    console.log("SecondAbility---","{method = onCreate}")
  }

  onForeground(): void {
    console.log("SecondAbility---","{method = onForeground}")
  }

  onBackground(): void {
    console.log("SecondAbility---","{method = onBackground}")
  }

  onDestroy(): void {
    console.log("SecondAbility---","{method = onDestroy}")
  }

  onWindowStageCreate(windowStage: window.WindowStage): void {
    console.log("SecondAbility---","{method = onWindowStageCreate}")
    windowStage.loadContent('pages/SecondPage', (err) => {
      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.');
    });
  }

  onWindowStageDestroy(): void {
    // Main window is destroyed, release UI related resources
    console.log("SecondAbility---","{method = onWindowStageDestroy}")
  }
}

那么如何进行UIAbility关闭呢?

首先需要为被关闭的UIAbility,在module.json5中配置一个属性:

image

其次调用方法:

import common from '@ohos.app.ability.common';

@Component
@Entry
struct SecondPage{

  build() {
    Column(){
      Text("这是第二个Ability的页面");
      Button("关闭").onClick(()=>{
        let context = getContext(this) as common.UIAbilityContext;
        // 关闭
        context.terminateSelf();
      })
    }
  }
}

如果不配置removeMissionAfterTerminate,UIAbility只会被退到后台,并不会被杀掉

UIAbility启动模式

启动模式一共4种:

(1)singnal: 单例模式,任务栈只有一个Ability;

(2)standard: 每次都创建一个新的Ability

(3)multion: 同standard;

(4)special: 定制模式。需要结合传参

多module之间调用

多module之间的跳转也使用want作为参数。例如跳转到featureModule:

首先需要对工程构建做配置:

image

image

跳转代码:

image