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

HarmonyOS开发(四):应用程序入口UIAbility

1、UIAbility概述

UIAbility

  • 一种包含用户界面的应用组件
  • 用于与用户进行交互
  • 系统调度的单元
  • 为应用提供窗口在其中绘制界同

注:每一个UIAbility实例,都对应一个最近任务列表中的任务。

一个应用可以有一个UIAbility也可以有多个UIAbility。

如一般的浏览器应用,通过一个UIAbility结合多页面的形式为用户提供服务

如一个聊天程序中添加一个与聊天不相关的“直播功能”场景,那可以把直播功能的内容独立为一个UIAbility,此时打开聊天应用的直播功能,这时要切换回聊天界面可通过最近任务列表切换实现(因为一个UIAbility实例,都对应一个最近任务列表中的任务)。

一个UIAbility可以对应多个页面,建议把一个独立的页面功能模块放到一个UIAbility中,以多页面的方式呈现。

2、UIAbility内页面的跳转和数据传递

页面间的导航可以通过页面路由router模块来实现 ,页面路由模块根据页面URL找到目标页面,从而实现页面的跳转。

2.1、页面跳转与参数接收

使用页面路由之前需要先导入router模块

import router from '@ohos.router';

2.1.1、页面跳转

页面跳转的两种方式:

方式一:router.pushUrl()

这个方法有两个参数:

url:表示要跳转到的页面

mode:可以取值为router.RouterMode.Single(单例模式)、router.RouterMode.Standard(多例模式,默认)

在单例模式下,如果目标页面URL在页面栈中已经存在同URL页面,离栈顶最近的同URL页面会被移动到栈顶,移动后的页面为新建页,原来的页面仍然存在栈中,页面栈中的元数数量不变;如果目标页面URL在页面栈中不存在同URL页面,按多例模式跳转,页面栈的元素数量会加1。

注:当页面栈的的元素数量较大或者超过32时,可以通过调用router.clear()方法清除页面栈中的所有历史页面,仅保留当前页面作为栈顶页面。

router.pushUrl({
    url: 'pages/Second',
    params: 'Index页面传过来的参数',
},router.RouterMode.Single)

方式二:router.replaceUrl()

这个方法有两个参数:

url:表示要跳转到的页面

mode:可以取值为router.RouterMode.Single(单例模式)、router.RouterMode.Standard(多例模式,默认)

在单列模式下,如果目标页面的URL在页面栈中已经存在同URL页面,离栈顶最近同URL页面会被移动到栈顶,替换当前页面,并销毁被替换的当前页面,移动后的页面为新建页面,页面栈的元素数量会减1;如果目标页面的URL在页面栈中不存在同URL页面,按多例模式跳转,页面栈元素数量不变。

注意:由于当前页面被替换并销毁,把以跳转回去后就无法再回退回来了

router.replaceUrl({
    url: 'pages/Second',
    params: {
        src: 'Index页面传过来的参数',
    }
},router.RouterMode.Single)

1.1.2、参数接收

跳转到的页面可以通过调用router.getParams()方法来接收传递过来的自定义参数

import router from '@ohos.router';

@Entry
@Component
struct Second {
    @State src: string = router.getParams()?.['src'];
    
    // 页面内容
}

2.2、页面返回和参数接收

2.2.1、页面返回

当我们跳转到某个页面,在这个页面中完成了一些功能后,如果希望返回到上一个页面,可以调用router.back()来实现,或者是在调用router.back()方法时增加options参数时增加url参来指定返回的具体页面。

注意:调用router.back()返回的目标页面需要在页面栈中存在才能正常返回,如果是replaceUrl()方法跳转的由于当前页面被销毁所以无法返回,如果在返回前调用了router.clear()清空了页面栈则也无法返回。

// 返回上一页面
router.back();

// 返回到指定页面
router.back({url: 'pages/Index'});

在调用router.back()方法之前,可以先调用router.enableAlertBeforeBackPage()方法开启页面返回询问提示对话框,如果点击取消则不做返回。

注意:这个方法当前已不推荐使用,可能是因为这个操作可能打断用户的交互行为

// 这个方法已经不推荐使用了,可能是因为会影响到交互的流畅性
router.enableAlertBeforeBackPage({
    message:'确定返回吗?'
});

在页面返回时可以同时添加自定义参数

router.back({
    url: 'pages/Index',
    params: {
        src: 'Second页面传过来的参数',
    }
})

2.2.2、接收返回参数

router.back()方法,不会新建页面,返回的是原来的页面,在原来页面中@State声明变量不会重复声明,也不会触发硕的aboutToAppear()生命周期回调,因此无法直接在变量声明以及页面aboutToAppear()生命周期回调中接收和解析返回的参数。

如果要接收参数可以在业务需要的位置进行参数解析。如:onPageShow()生命周期回调函数中进行解析。

import router from '@ohos.router';

@Entry
@Component
struct Index {
    @State src: string = '';

    onPageShow() {
        this.src = router.getParams()?.['src'];
    }

    // 页面内容
}

3、UIAbility生命周期

UIAbility生命周期有四个:Create、Foreground、Background、Destroy

窗口管理器在UIAbility中管理UI界面功能的两个生命周期回调:WindowStageCreate、WindowStageDestroy

Create状态

在UIAbility实例创建时触发,系统会调用onCreate回调。可以在其中做相关的初始化操作。

import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';

export default class EntryAbility extends UIAbility {

    onCreate(want, launchParam) {
        // 应用初始化操作
        ...
    }
}

WindowStageCreate

UIAbility实例创建完成后,在进入Foreground之前,系统会创建一个WindowStage。

每一个UIAbility实例都对应持有一个WindowStage实例。

WindowStage为本地窗口管理器,用于管理窗口相关的内容,如界面相关的获焦/失焦、可见/不可见

可以在onWindowStageCreate回调中,设置UI页面加载、设置WindowStage的事件订阅

在onWindowStageCreate(windowStage)中通过loadContent接口设置应用要加载的页面。

import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';

export default class EntryAbility extends UIAbility {

    ...
    
    onWindowStageCreate(windowStage: window.WindowStage) {
        // 设置UI页面加载
        // 设置WindowStage事件订阅
        ...
        
        windowStage.loadContent('pages/Index',(err, data) => {
            ...
        });
    }
    
    ...
}

Foreground和Background状态

上面的状态分别是UIAbility切换至前台或者切换至后台时触发。它们分别对应的是onForeground回调和onBackground回调。

onForeground回调:在UIAbility的UI页面可见之前,即UIAbility切换至前台时触。可以在其中申请系统需要的资源,或者重新申请在onBackground中释放的资源。

onBackground回调:在UIAbility的UI页面完全不可见之后,即UIAbility切换至后台时候触发。可以在onBackground回调中释放UI页面不可见时无用的资源,或者在此回调中执行较为耗时的操作,例如状态保存等。

import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';

export default class EntryAbility extends UIAbility {

    ...
    
    onForeground() {
        // 申请需要的资源
        ...
    }

    onBackground() {
        // 释放资源,或者执行较为耗时的任务
        ...
    }
}

WindowStageDestroy

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

import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';

export default class EntryAbility extends UIAbility {

    ...
    
    onWindowStageDestroy() {
        // 释放UI页面资源
        ...
    }
}

Destroy状态

在UIAbility销毁时触发。可以在onDestroy回调中进行系统资源的释放、数据的保存等操作。

import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';

export default class EntryAbility extends UIAbility {
    ...

    onDestroy() {
        // 系统资源的释放、数据的保存等
        ...
    }
}

4、UIAbility启动模式

UIAbility当前支持single(单实例模式)、multiton(多实例模式)和specified(指定实例模式)三种启动模式。

singleton(单实例模式)

访问应用后,回到桌面,再次打开应用,显不的仍是用户当前访问界面。

每次调用startAbility()方法时,如果应用进程中该类型的UIAbility实例已经存在,则复用系统中的UIAbility实例,系统中只存在唯一一个该UIAbility实例。

singleton启动模式在module.json5文件中中“launchType”字段配置为“singleton”即可。

multiton(多实例模式)

每次调用startAbility()方法时,都会在应用进程中创建一个该类型的UIAbility实例。即在最近任务列表中可以看到有多个该类型的UIAbility实例。

multiton启动模式,在module.json5文件中的“launchType”字段配置为“multiton”即可。

specified(指定实例模式)

在UIAbility实例创建之前,会先进入AbilityStage的onAcceptWant回调,在onAcceptWant回调中为每一个UIAbility实例创建一个Key,后续每次调用startAbility()方法创建该类型的UIAbility实例都会询问使用哪个Key对应的UIAbility实例来响应startAbility()请求。

specified启动模式使用步骤:

在module.json5文件中“launchType”字段配置为“specified”。

在调用startAbility()方法的want参数中,增加一个自定义参数来区别UIAbility实例。

// 在启动指定实例模式的UIAbility时,给每个UIAbility实例配置一个独立的key标识
function getInstance() {
    ...
}

let content:common.UIAbilityContext = '...'    // context为调用方UIAbility的UIAbilityContext
let want: Want = {
    deviceId: '', // deviceId为空表示本设备
    bundleName: 'com.example.myapplication',
    abilityName: 'SpecifiedAbility',
    moduleName: 'specified', // moduleName非必选
    parameters: { // 自定义信息
        instanceKey: getInstance(),
    },
}
context.startAbility(want).then(() => {
    ...
}).catch((err: BusinessError) => {
    ...
})

在被拉起方UIAbility对应的AbilityStage的onAcceptWant生命周期回调中,解析传入的want参数,获取“instanceKey”自定义参数。根据业务需要返回一个该UIAbility实例的字符串Key标识。如果之前启动过此Key标识的UIAbility,则会将之前的UIAbility拉回前台并获焦,而不创建新的实例,否则创建新的实例并启动

onAcceptWant(want: Want): string {
    // 在被启动方的AbilityStage中,针对启动模式为specified的UIAbility返回一个UIAbility实例对应的一个Key值
    // 当前示例指的是device Module的EntryAbility
   if (want.abilityName === 'MainAbility') {
        return `DeviceModule_MainAbilityInstance_${want.parameters.instanceKey}`;
    }
    return '';
}

5、案列实践

1、新增EmptyAbility,Stage模式项目:MyApplication1

2、在生成项目的Index页面(pages/Index.ets)修改为如下

import router from '@ohos.router';  // 实现页面的路由

@Entry
@Component
struct Index {
  @State src: string = ''
  // 页面显示时的回调函数
  onPageShow() {
    this.src = router.getParams()?.['src'];
  }

  build() {
    Row() {
      Column() {
        Text('index Page')
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
        if(this.src) {
          Text(this.src)
        }
        Button('Next')
          .type(ButtonType.Capsule)
          .backgroundColor(Color.Blue)
          .fontColor(Color.White)
          .onClick(() => {

            // 跳转还可以使用replaceUrl,pushUrl是在页面栈中移动,replaceUrl是在页面栈移动后替换当前页面并销毁当前页面,这里back就回不来了
            router.pushUrl({
              url: 'pages/Second',
              params: {
                src: 'Index页面传递过来的数据',
              }
            },router.RouterMode.Single)
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

3、新增一个页面Second(pages/Second.ets)

import router from '@ohos.router';

@Entry
@Component
struct Second {
  // 获取页面传递过来的参数
  @State src: string = router.getParams()?.['src'];

  build() {
    Row() {
      Column() {
        Text('second Page')
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
        Text(this.src)
        Button('back')
          .type(ButtonType.Capsule)
          .backgroundColor(Color.Blue)
          .fontColor(Color.White)
          .onClick(() => {
            // 这个方法已经不推荐使用了,可能是因为会影响到交互的流畅性
            router.enableAlertBeforeBackPage({
              message:'确定返回吗?'
            });

            // 这里的back方法也可以增加options参数指定跳转回的页面,返回时也可以带上参数返回
            // router.back();
            // router.back({url:'pages/Index'});
            router.back({
              url: 'pages/Index',
              params:{
                src: 'Second页面带过来的参数',
              }
            })
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

注意:新增第二个页面Second时我们在pages上右键选择New-->Page

如果我们不是新增的Page,而是直接新增一个ets的文件,则还需要对main_pages.json文件的src下新增,"pages/Second",这个文件所在目录是:src/main/resources/base/profile/main_pages.json


http://www.kler.cn/news/134673.html

相关文章:

  • 小米手环8pro重新和手机配对解决办法
  • java: 无法访问org.mybatis.spring.annotation.MapperScan
  • 智能货柜:无人零售行业的新宠
  • JDBC编程
  • 阿里云CentOS主机开启ipv6
  • Windows10下Maven3.9.5安装教程
  • 代码逻辑修复与其他爬虫ip库的应用
  • 探索SPI:深入理解原理、源码与应用场景
  • 【Matterport3D模拟器安装详细教程】适用于离散视觉语言导航任务的环境部署与安装
  • python django 小程序博客源码
  • 如何保护PayPal账户安全:防止多个PayPal账号关联?
  • 【服务器学习】hook模块
  • SIMULIA|Abaqus 2022x新功能介绍第三弹
  • 【面试经典150 | 数学】回文数
  • 计算机毕业设计选题推荐-个人博客微信小程序/安卓APP-项目实战
  • 硬盘无法格式化怎么办?
  • ModStartCMS v7.6.0 CMS备份恢复优化,主题开发文档更新
  • ESP32 Arduino实战协议篇-搭建独立的 Web 服务器
  • APP源码|智慧校园电子班牌源码 智慧校园云平台
  • Elasticsearch备份与还原:使用elasticdump
  • C#入门(5):数组、一维数组,二维数组、交错数组、数组复制
  • 数据资产入表,给企业带来的机遇和挑战
  • 02-1解析xpath
  • String的字符串拼接
  • 通付盾Web3专题 | KYT/AML:Web3合规展业的必要条件
  • 蓝桥杯 vector
  • nvm 安装后出现的各种问题解决方法
  • Redis 学习
  • linux 安装中文字体
  • vue中绑定class样式和条件渲染