鸿蒙开发(三)理解UIAbility

    前文提到过,在使用DevEco创建鸿蒙项目的时候,会选择Empty Ability,那么这个Ability是什么呢?其实对比Android Studio创建Android羡慕时选择的Empty Activity,感觉Harmony的Ability更像是Android的Activity,但只能说像,不完全等同。本篇,我们就基于API9一起探索下UIAbility。因为本人是Android开发者,所以文章中会时不时的跟Android对比。

鸿蒙系列上一篇

鸿蒙开发(二)鸿蒙DevEco3.X开发环境搭建-CSDN博客文章浏览阅读1k次,点赞13次,收藏19次。上篇说到,鸿蒙开发目前势头旺盛,头部大厂正在如火如荼地进行着,华为也对外宣称已经跟多个厂商达成合作。目前看来,对于前端或客户端开发人员来说,掌握下鸿蒙开发还是有些必要性的。如果你之前是从事Android开发的,那么你会发现除了开发语言,鸿蒙基本上就跟Android一模一样。在正式进行鸿蒙开发前,首先是搭建DevEco开发环境,本篇介绍下如何基于DevEco3.X搭建鸿蒙开发环境并且运行第一行代码-Hello World。https://blog.csdn.net/qq_21154101/article/details/135215940?spm=1001.2014.3001.5501

目录

一、UIAbility概述

二、UIAbility生命周期

1、生命周期概述

2、onCreate

3、onWindowStageCreate和onWindowStageDestroy

4、 onForeground和onBackground

    onForeground()回调,在UIAbility实例切换至前台时触发,在UIAbility的UI界面可见之前调用。onBackground()回调,在UIAbility实例切换至后台时候触发,在UIAbility的UI界面完全不可见之后调用。

5、 onDestroy

三、UIAbility启动模式

1、 singleton启动模式

2、 standard启动模式

3、 specified启动模式

四、UIAbility组件间交互 

1、创建UIAbility

2、创建页面

3、绑定UIAbility和页面


一、UIAbility概述

    在介绍UIAbility之前,我们先看下Ability,Ability直译过来就是能力。什么能力呢?引用官方开发者社区对Ability的解释:

Ability是应用/服务所具备的能力的抽象,一个Module可以包含一个或多个Ability。应用/服务先后提供了两种应用模型:

  • FA(Feature Ability)模型: API 7开始支持的模型,已经不再主推。
  • Stage模型:API 9开始新增的模型,是目前主推且会长期演进的模型。在该模型中,由于提供了AbilityStage、WindowStage等类作为应用组件和Window窗口的“舞台”,因此称这种应用模型为Stage模型。

    Stage模型包含两种Ability组件类型:

    • UIAbility组件:包含UI界面,提供展示UI的能力,主要用于和用户交互。
    • ExtensionAbility组件:提供特定场景的扩展能力,满足更多的使用场景。

    可以看到,Ability是应用/服务所具备的能力的抽象。Stage模型的Ability是主流,因此,本篇我们也基于Stage模型下,对UIAbility进行讲解。

    UIAbility组件是一种包含UI界面的应用组件,主要用于和用户交互。UIAbility组件是系统调度的基本单元,为应用提供绘制界面的窗口。一个UIAbility组件中可以通过多个页面来实现一个功能模块。

    需要注意的是:

每一个UIAbility组件实例,都对应于一个最近任务列表中的任务。

    因此,对于开发者而言,可以根据具体的场景选择单个还是多个UIAbility。

二、UIAbility生命周期

    上面也多次提到过,UIAbility组件是一种包含UI界面的应用组件,主要用于和用户交互。既然是包含了跟用户交互的UI界面的应用组件,那么肯定就离不开生命周期。即UIAbility从创建到跟用户交互到最终销毁的整个过程。接下来探索下UIAbility的生命周期。

1、生命周期概述

    当用户打开、切换和返回到对应应用时,应用中的UIAbility实例会在其生命周期的不同状态之间转换。UIAbility类提供了一系列回调,通过这些回调可以知道当前UIAbility实例的某个状态发生改变,会经过UIAbility实例的创建和销毁,或者UIAbility实例发生了前后台的状态切换。

    UIAbility的生命周期包括onCreate、onForeground、onBackground、onDestroy四个状态,如下图所示:

2、onCreate

    onCreate状态为在应用加载过程中,UIAbility实例创建完成时触发,系统会调用onCreate()回调。可以在该回调中进行应用初始化操作,例如变量定义资源加载等,用于后续的UI界面展示。

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

export default class EntryAbility extends UIAbility {
    onCreate(want, launchParam) {
        // 应用初始化
    }
    // ...
}

3、onWindowStageCreate和onWindowStageDestroy

    UIAbility实例创建完成之后,在进入Foreground之前,系统会创建一个WindowStage。WindowStage创建完成后会进入onWindowStageCreate()回调,可以在该回调中通过loadContent()方法设置应用要加载的页面并根据需要订阅WindowStage的事件(获焦/失焦、可见/不可见)。

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

export default class EntryAbility extends UIAbility {
    onWindowStageCreate(windowStage: Window.WindowStage) {
        // 设置WindowStage的事件订阅(获焦/失焦、可见/不可见)

        // 设置UI界面加载
        windowStage.loadContent('pages/Index', (err, data) => {
            // ...
        });
    }
}

    同样的,在UIAbility实例销毁之前,则会先进入onWindowStageDestroy()回调,可以在该回调中释放UI界面资源。例如在onWindowStageDestroy()中注销获焦/失焦等WindowStage事件。

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

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

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

4、 onForeground和onBackground

    onForeground()回调,在UIAbility实例切换至前台时触发,在UIAbility的UI界面可见之前调用。onBackground()回调,在UIAbility实例切换至后台时候触发,在UIAbility的UI界面完全不可见之后调用。

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

export default class EntryAbility extends UIAbility {
    onForeground() {
        // 申请系统需要的资源,或者重新申请在onBackground中释放的资源
    }

    onBackground() {
        // 释放UI界面不可见时无用的资源,或者在此回调中执行较为耗时的操作
        // 例如状态保存等
    }
}

5、 onDestroy

    onDestroy状态在UIAbility实例销毁时触发。可以在onDestroy()回调中进行系统资源的释放、数据的保存等操作。例如调用terminateSelf()方法停止当前UIAbility实例,从而完成UIAbility实例的销毁;或者用户使用最近任务列表关闭该UIAbility实例,完成UIAbility的销毁。

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

export default class EntryAbility extends UIAbility {
    onDestroy() {
        // 系统资源的释放、数据的保存等
    }
}

三、UIAbility启动模式

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

  • singleton启动模式(单实例模式)
  • standard启动模式(标准实例模式)
  • specified启动模式(指定实例模式)

1、 singleton启动模式

    singleton启动模式为单实例模式,也是默认情况下的启动模式。每次调用startAbility()方法时,如果应用进程中该类型的UIAbility实例已经存在,则复用系统中的UIAbility实例。系统中只存在唯一一个该UIAbility实例,即在最近任务列表中只存在一个该类型的UIAbility实例。

    应用的UIAbility实例已创建,该UIAbility配置为单实例模式,再次调用startAbility()方法启动该UIAbility实例,此时只会进入该UIAbility的onNewWant回调,不会进入其onCreate()和onWindowStageCreate()生命周期回调。 

     如果需要配置单实例模式,module.json5中的"launchType"字段配置为"singleton"即可。

2、 standard启动模式

    standard启动模式为标准实例模式,每次调用startAbility()方法时,都会在应用进程中创建一个新的该类型UIAbility实例。即在最近任务列表中可以看到有多个该类型的UIAbility实例。这种情况下可以将UIAbility配置为standard(标准实例模式)。

    如果需要配置单实例模式,module.json5中的"launchType"字段配置为"standard"即可。

3、 specified启动模式

    specified启动模式为指定实例模式,针对一些特殊场景使用。在UIAbility实例创建之前,允许开发者为该实例创建一个唯一的字符串Key,创建的UIAbility实例绑定Key之后,后续每次调用startAbility()方法时,都会询问应用使用哪个Key对应的UIAbility实例来响应startAbility()请求。运行时由UIAbility内部业务决定是否创建多实例,如果匹配有该UIAbility实例的Key,则直接拉起与之绑定的UIAbility实例,否则创建一个新的UIAbility实例。

四、UIAbility组件间交互 

    当一个应用内包含多个UIAbility时,存在应用内启动UIAbility的场景。那么,如何在一个UIAbility中启动另一个UIAbility呢?

    假设应用中有两个UIAbility:EntryAbility和FuncAbility(可以在应用的一个Module中,也可以在的不同Module中),需要从EntryAbility的页面中启动FuncAbility。

1、创建UIAbility

    创建新的UIAbility步骤如下:New -> Ability,跟Android的Activity类似,同时需要在对应的配置文件中进行注册。Android是AndroidManifest.xml文件,而harmony则是module.json5文件。如下图所示,是我创建的一个Demo,默认的EntryAbility继承自UIAbility,声明信息如下:

    UIAbility部分声明信息详解(大部分标签不用多解释,跟Android类似):

{
  "module": {
    // ...
    "abilities": [
      {
        "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", // UIAbility组件启动页面背景颜色资源文件的索引
        "exported": true, // 标识当前UIAbility组件是否可以被其他应用调用
        "skills": [ // 标识当前Ability组件能够接收的Want的特征集,为数组格式[类似安卓的IntentFilter]。
          {
            "entities": [
              "entity.system.home"
            ],
            "actions": [
              "action.system.home"
            ]
          }
        ]
      }
    ]
  }
}

    更完整的声明信息见module.json5配置文件 

2、创建页面

    仅UIAbility也可以,但是没有可展示的页面有点奇奇怪怪。所以,我们给新建的FuncUIAbility创建一个页面Func,代码很简单,直接赋值Index.ets,修改一下message用来区分:

3、绑定UIAbility和页面

    这个在讲生命周期的时候说过了,在onWindowStageCreate中调用windowStage.loadContent即可:

  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/Func', (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) ?? '');
    });
  }

注意:需要在resources/profile/main_pages.json中添加新创建的page,,否则UIAbility中无法展示该页面!!!

 如下图所示:

4、启动UIAbility

  openFuncUiAbility(){
    // 调起app内其他的UIAbility
    let want: Want = {
      deviceId: '', // deviceId为空表示本设备
      bundleName: 'com.example.tuduharmonydemo', // 必填
      moduleName: '', // moduleName为空表示本模块
      abilityName: 'FuncAbility', // 必填
      parameters: { // 自定义信息
        info: '来自EntryAbility Index页面',
      },
    }
    this.context.startAbility(want).then(() => {
      hilog.info(0x0000, this.tag, 'Succeeded in starting ability.');
    }).catch((err) => {
      hilog.error(0x0000, this.tag, `Failed to start ability. Code is ${err.code}, message is ${err.message}`);
    })
  }

    本篇介绍了UIAbility,包括UIAbility概述、生命周期、启动模式以及UIAbility组件之间的交互。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/323529.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

高效微调大型预训练模型的Prompt Learning方法

目录 前言1 prompt learning简介2 prompt learning步骤2.1 选择模型2.2 选择模板(Template)2.3 Verbalizer的构建 3 Prompt Learning训练策略3.1 Prompting组织数据,优化参数3.2 增加Soft Prompts,冻结模型,优化Prompt…

参与直播领取龙年大礼盒!23年Coremail社区年终福利大放送

2023年终福利大放送 Coremail 管理员社区是由 Coremail 邮件安全团队、服务团队及多条产品线共同维护,集 7*24h 在线自助查询、技术问答交流、大咖互动分享、资料下载等功能于一体,专属于 Coremail 邮件管理员、安全员成长互动的知识库社区。 转眼间&am…

详解电源动态响应的测试方法及重要性 -纳米软件

电源动态响应测试的重要性 电源动态响应测试是为了检测电源系统在负载变化、输入电压变化情况下的性能表现,包括响应速度、稳定性以及恢复能力等,从而判断电源能否快速、准确地恢复到正常工作状态,为电源的优化设计提供依据。 动态响应能力影…

2024谷歌SEO自学基础入门

2024年可能会迎来大航海时代,国内各企业也加速了出海的步伐!! (看总额,今年中国跨境电商,前三季度进出口1.7万亿元人民币,创造了14.4%的增长。 看体量,过去五年,中国跨…

蓝桥杯每日一题----货物摆放

题目 分析 上来一看,三个for循环,从1到n,寻找满足lwhn的个数,但是这样根本跑不出来答案,n太大了,1e15的级别,O(n)的时间复杂度都不行,更何况是O(…

RC4(CTFshow re2)

基本原理 RC4属于对称密码算法中的流密码加密算法 什么是对称密码? 使用同一个密钥进行加密和解密 什么是流密码? 一个字节一个字节的进行加密/解密 RC4密钥长度是可以变的,面向字节操作 它以一个足够大的表s为基础 对表进行非线性变换&…

vue 使用mock模拟数据

vue 使用mock模拟数据 安装依赖 cnpm install axios --save cnpm install mockjs --save-dev cnpm install json5 --save-dev在根目录下,新建一个mock文件,且创建如下文件 utils.js index.js const Mock require(mockjs) const { param2Obj } …

SSH远程访问与控制

目录 ssh优点 作用 SSH的 软件 公钥首次连接原理 ssh远程登录 shh命令 远程连接 直接连接先输入ssh IP 连接指定用户 在 /etc/ssh/sshd_config下面修改端口号 修改服务端配置文件 ​编辑 白名单,只能登录本机的mcb用户 SSH服务的最佳实践 openSSH 服…

同城配送小程序开发 同城生意一键掌控

同城配送小程序开发大概要多少费用?一般影响同城配送小程序开发费用的因素有以下几种: 1、小程序功能性。 生鲜小程序的价钱也会受到它的功能产生的影响,一些基本功能,包含商品订单、产品管理、团团长管理方法、数据分析、配送管理…

软件测试|Python如何处理配置文件

配置文件在软件开发中起到了非常重要的作用,它允许开发者将应用程序的设置和参数存储在一个易于管理和修改的地方,而不是硬编码在代码中。Python有多种处理配置文件的方式,本文将介绍其中两种最常用的方法:使用configparser库和使…

SpringBoot教程(五) | SpringBoot中Controller详解

SpringBoot教程(五) | SpringBoot中Controller详解 SpringBoot整合SpringMvc其实千面一直讲的都是。只需要我们在pom文件中引入 web的starter就可以了,然后我们就可以正常使用springMvc中的功能了。所以本篇文章可能更多的是回顾,回顾一下springMVC中的…

01.15

#include "widget.h" #include <QApplication>int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();VideoCapture mv;mv.open("D:\\opencv\\heads\\01.mp4");//定义一个存放视频里读取到的一帧图像Mat src;//定义一个存…

自定义typora样式,如引用块颜色

要进行自定义typora中的样式&#xff0c;你最好像我一样&#xff0c;自己新建一个主题 首先文件->偏好设置->打开主题文件夹 然后自己新建一个文件夹&#xff0c;可以命名为selfmake&#xff0c;并copy一下github.css一个副本&#xff0c;将其命名为selfmake.css&#…

NLP论文阅读记录 - 2021 | WOS 基于动态记忆网络的抽取式摘要

文章目录 前言0、论文摘要一、Introduction1.1目标问题1.2相关的尝试1.3本文贡献 二.前提三.本文方法四 实验效果4.1数据集4.2 对比模型4.3实施细节4.4评估指标4.5 实验结果4.6 细粒度分析 五 总结思考 前言 Extractive Summarization Based on Dynamic Memory Network&#xf…

百亿补贴链接的快速控价方式

各大电商平台都有推出百亿补贴这个通道&#xff0c;作为低价引流的方式&#xff0c;百亿补贴越来越受到消费者认可&#xff0c;对于平台来说&#xff0c;其带来的流量也是巨大的&#xff0c;而对于品牌来说&#xff0c;百亿补贴的价格对渠道的影响非常大&#xff0c;如果百亿补…

Linux之引导和服务篇

系统引导是操作系统运行的开始&#xff0c;在用户能够正常登录之前&#xff0c;Linux的引导过程完成了一系列的初始化任务&#xff0c;并加载必要的程序和命令终端&#xff0c;为用户登录做好准备。 一. 引导过程 开机自检--->MBR引导--->GRUB菜单--->加载Linux内核-…

pandas进行数据计算时如何处理空值的问题?

目录 1.数据预览&#xff1a; 2.解决方法 &#xff08;1&#xff09;问题示例 &#xff08;2&#xff09;方法 A.方法一 B.方法二 1.数据预览&#xff1a; 2.解决方法 &#xff08;1&#xff09;问题示例 如下图如果不理睬这些空值的话&#xff0c;计算总分便也会是空值…

Chapter 10 类的继承(上篇)

目的&#xff1a;了解三种继承方式&#xff0c;并清楚其中的差别 &#x1f383;&#x1f383;&#x1f383;&#x1f383;&#x1f383;&#x1f383;&#x1f383;&#x1f383;&#x1f383;&#x1f383;&#x1f383;&#x1f383;&#x1f383;&#x1f383;&#x1f383;…

安科瑞微电网能量监测系统Acrel-2000MG 储能电站监测预警

在新型电力系统中&#xff0c;储能将成为至关重要的一环&#xff0c;是分布式光伏、风电等新能源消纳以及电网安全保障必要保障&#xff0c;在电源侧、电网侧、用户侧都会得到广泛的应用。《电力现货市场基本规则&#xff08;征求意见稿&#xff09;》以及各地出台的扶持政策给…

Axure RP软件揭秘:设计师的秘密武器

Axure rp是一种快速原型设计工具&#xff0c;可以制作高度互动的HTML原型。设计师不仅可以使用Axure绘制线框图和原型&#xff0c;还可以在Axure rp中完成一系列用户体验设计。在本文中&#xff0c;我们将根据用户体验设计师的真实经验&#xff0c;触发用户体验设计师的实际工作…