当前位置:   article > 正文

鸿蒙开发(三)探索UIAbility_鸿蒙开发 handler.terminateself();

鸿蒙开发 handler.terminateself();

    前文提到过,在使用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 

5、 onDestroy

三、UIAbility启动模式

1、 singleton启动模式

2、 standard启动模式

3、 specified启动模式

四、UIAbility组件间交互 

1、创建UIAbility

2、创建页面

3、绑定UIAbility和页面

4、启动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界面展示。

  1. import UIAbility from '@ohos.app.ability.UIAbility';
  2. import Window from '@ohos.window';
  3. export default class EntryAbility extends UIAbility {
  4. onCreate(want, launchParam) {
  5. // 应用初始化
  6. }
  7. // ...
  8. }

3、onWindowStageCreate和onWindowStageDestroy

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

  1. import UIAbility from '@ohos.app.ability.UIAbility';
  2. import Window from '@ohos.window';
  3. export default class EntryAbility extends UIAbility {
  4. onWindowStageCreate(windowStage: Window.WindowStage) {
  5. // 设置WindowStage的事件订阅(获焦/失焦、可见/不可见)
  6. try {
  7. windowStage.on('windowStageEvent', (data) => {
  8. let stageEventType: window.WindowStageEventType = data;
  9. switch (stageEventType) {
  10. case window.WindowStageEventType.SHOWN: // 可见
  11. hilog.info(0x0000, this.tag, 'windowStage SHOWN.');
  12. break;
  13. case window.WindowStageEventType.ACTIVE: // 获焦
  14. hilog.info(0x0000, this.tag, 'windowStage ACTIVE.');
  15. break;
  16. case window.WindowStageEventType.INACTIVE: // 失焦
  17. hilog.info(0x0000, this.tag, 'windowStage INACTIVE.');
  18. break;
  19. case window.WindowStageEventType.HIDDEN: // 不可见
  20. hilog.info(0x0000, this.tag, 'windowStage HIDDEN.');
  21. break;
  22. default:
  23. break;
  24. }
  25. });
  26. } catch (exception) {
  27. hilog.error(0x000, this.tag, 'Failed to enable the listener for window stage event changes. Cause:' +
  28. JSON.stringify(exception));
  29. }
  30. // 设置UI界面加载
  31. windowStage.loadContent('pages/Index', (err, data) => {
  32. // ...
  33. });
  34. }
  35. }

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

  1. import UIAbility from '@ohos.app.ability.UIAbility';
  2. import Window from '@ohos.window';
  3. export default class EntryAbility extends UIAbility {
  4. // ...
  5. onWindowStageDestroy() {
  6. // 释放UI界面资源
  7. }
  8. }

4、 onForeground和onBackground 

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

  1. import UIAbility from '@ohos.app.ability.UIAbility';
  2. export default class EntryAbility extends UIAbility {
  3. onForeground() {
  4. // 申请系统需要的资源,或者重新申请在onBackground中释放的资源
  5. }
  6. onBackground() {
  7. // 释放UI界面不可见时无用的资源,或者在此回调中执行较为耗时的操作
  8. // 例如状态保存等
  9. }
  10. }

5、 onDestroy

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

  1. import UIAbility from '@ohos.app.ability.UIAbility';
  2. import Window from '@ohos.window';
  3. export default class EntryAbility extends UIAbility {
  4. onDestroy() {
  5. // 系统资源的释放、数据的保存等
  6. }
  7. }

三、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。

注意:我们暂且只在EntryAbility可见时去跳转FuncAbility,不在页面控件的点击事件中去触发。页面和UIAbility之间的交互,在后续的文章中会讲到。

1、创建UIAbility

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

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

  1. {
  2. "module": {
  3. // ...
  4. "abilities": [
  5. {
  6. "name": "EntryAbility", // UIAbility组件的名称
  7. "srcEntry": "./ets/entryability/EntryAbility.ts", // UIAbility组件的代码路径
  8. "description": "$string:EntryAbility_desc", // UIAbility组件的描述信息
  9. "icon": "$media:icon", // UIAbility组件的图标
  10. "label": "$string:EntryAbility_label", // UIAbility组件的标签
  11. "startWindowIcon": "$media:icon", // UIAbility组件启动页面图标资源文件的索引
  12. "startWindowBackground": "$color:start_window_background", // UIAbility组件启动页面背景颜色资源文件的索引
  13. "exported": true, // 标识当前UIAbility组件是否可以被其他应用调用
  14. "skills": [ // 标识当前Ability组件能够接收的Want的特征集,为数组格式[类似安卓的IntentFilter]。
  15. {
  16. "entities": [
  17. "entity.system.home"
  18. ],
  19. "actions": [
  20. "action.system.home"
  21. ]
  22. }
  23. ]
  24. }
  25. ]
  26. }
  27. }

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

2、创建页面

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

3、绑定UIAbility和页面

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

  1. onWindowStageCreate(windowStage: window.WindowStage) {
  2. // Main window is created, set main page for this ability
  3. hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
  4. windowStage.loadContent('pages/Func', (err, data) => {
  5. if (err.code) {
  6. hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
  7. return;
  8. }
  9. hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
  10. });
  11. }

注意:如果是直接赋值的Page,需要在resources/profile/main_pages.json中添加新创建的page,,否则UIAbility中无法展示该页面!!!如果New - Page的方式创建,则自动更新,无需关注。

 如下图所示:

4、启动UIAbility

   在EntryUIAbility加载完页面时,也即onWindowStageCreate中调用windowStage.loadContent

后,去触发跳转FuncUIAbility,代码如下:

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

    初学的同学可能不清楚bundleName应该怎么填写,这里特别讲解下。bundleName,在AppScope/resources/app.json5中描述的。如下图所示:

    看下录屏的效果: ​​​​​​​

    本篇介绍了鸿蒙开发的重要组件UIAbility,介绍了UIAbility是什么,并且围绕UIAbility的生命周期和三种启动模式进行了详细的阐述。既然是组件,固然离不开组件之间的交互。因此,在最后讲解了UIAbility组件之间的交互。下一篇,我们一起学习下UIAbility和Page之间的交互。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/231207
推荐阅读
相关标签
  

闽ICP备14008679号