HarmonyOS之 应用程序页面UIAbility

一 UIAbility介绍:

1.1 UIAbility是一种包含用户界面的应用组件,主要用于和用户进行交互

1.2 UIAbility也是系统调度的单元,为应用提供窗口在其中绘制界面

二 UIAbility跳转和传参

2.1 页面间的导航可以通过页面路由router模块来实现。页面路由模块根据页面url找到目标页面,从而实现跳转。通过页面路由模块,可以使用不同的url访问不同的页面,包括跳转到UIAbility内的指定页面、用UIAbility内的某个页面替换当前页面、返回上一页面或指定的页面等

2.2 在使用页面路由之前,需要先导入router模块,如下代码所示。

TypeScript 复制代码
import router from '@ohos.router';

2.3 跳转页面方式一:router.pushUrl 增加页面,params是传递的参数

TypeScript 复制代码
router.pushUrl({
  url: 'pages/Second',
  params: {
    src: 'Index页面传来的数据',
  }
}, router.RouterMode.Single)

2.4 跳转页面方式二: router.replaceUrl替换页面,params是传递的参数

TypeScript 复制代码
router.replaceUrl({
  url: 'pages/Second',
  params: {
    src: 'Index页面传来的数据',
  }
}, router.RouterMode.Single)

2.5 接收参数,通过调用router.getParams()方法获取Index页面传递过来的自定义参数

TypeScript 复制代码
import router from '@ohos.router';

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

2.6 效果示意如下图所示。在Index页面中,点击"Next"后,即可从Index页面跳转到Second页面,并在Second页面中接收参数和进行页面刷新展示

三 UIAbility返回上一页面和传参

3.1 返回页面:调用router.back()方法时增加可选的options参数(增加url参数)返回到指定页面

返回上一个页面

TypeScript 复制代码
router.back();

3.2 返回指定页面,并传参

TypeScript 复制代码
router.back({
  url: 'pages/Index',
  params: {
    src: 'Second页面传来的数据',
  }
})

3.3 返回页面接收参数

TypeScript 复制代码
import router from '@ohos.router';

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

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

  // 页面刷新展示
  ...
}

3.4 效果示意图如下图所示。在Second页面中,点击"Back"后,即可从Second页面返回到Index页面,并在Index页面中接收参数和进行页面刷新展示

四 UIAbility生命周期

4.1 生命周期图示

4.2 Create:

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

TypeScript 复制代码
import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';

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

4.3 onWindowStageCreate:

UIAbility实例创建完成之后,在进入Foreground之前,系统会创建一个WindowStage。每一个UIAbility实例都对应持有一个WindowStage实例,可以在onWindowStageCreate回调中,设置UI页面加载、设置WindowStage的事件订阅

TypeScript 复制代码
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) => {
            ...
        });
    }
    ...
}

4.4 onForeground:

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

TypeScript 复制代码
import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';

export default class EntryAbility extends UIAbility {
    ...

    onForeground() {
        // 申请系统需要的资源,或者重新申请在onBackground中释放的资源
        ...
    }

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

4.5 onWindowStageDestroy:

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

TypeScript 复制代码
import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';

export default class EntryAbility extends UIAbility {
    ...

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

4.6 Destroy:

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

TypeScript 复制代码
import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';

export default class EntryAbility extends UIAbility {
    ...

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

五 UIAbility启动模式

5.1 UIAbility当前支持singleton(单实例模式)、multiton(多实例模式)和specified(指定实例模式)3种启动模式

5.2 singleton(单实例模式):

  • 当用户打开浏览器或者新闻等应用,并浏览访问相关内容后,回到桌面,再次打开该应用,显示的仍然是用户当前访问的界面。

这种情况下可以将UIAbility配置为singleton(单实例模式)。每次调用startAbility()方法时,如果应用进程中该类型的UIAbility实例已经存在,则复用系统中的UIAbility实例,系统中只存在唯一一个该UIAbility实例

TypeScript 复制代码
{
   "module": {
     ...
     "abilities": [
       {
         "launchType": "singleton",
         ...
       }
     ]
  }
}

5.3 multiton(多实例模式):

  • 用户在使用分屏功能时,希望使用两个不同应用(例如备忘录应用和图库应用)之间进行分屏,也希望能使用同一个应用(例如备忘录应用自身)进行分屏。
  • 这种情况下可以将UIAbility配置为multiton(多实例模式)。每次调用startAbility()方法时,都会在应用进程中创建一个该类型的UIAbility实例
TypeScript 复制代码
{
   "module": {
     ...
     "abilities": [
       {
         "launchType": "multiton",
         ...
       }
     ]
  }
}

5.4 specified(指定实例模式):

  • 用户打开文档应用,从文档应用中打开一个文档内容,回到文档应用,继续打开同一个文档,希望打开的还是同一个文档内容;以及在文档应用中新建一个新的文档,每次新建文档,希望打开的都是一个新的空白文档内容。
  • 这种情况下可以将UIAbility配置为specified(指定实例模式)。在UIAbility实例新创建之前,允许开发者为该实例创建一个字符串Key,新创建的UIAbility实例绑定Key之后,后续每次调用startAbility方法时,都会询问应用使用哪个Key对应的UIAbility实例来响应startAbility请求。如果匹配有该UIAbility实例的Key,则直接拉起与之绑定的UIAbility实例,否则创建一个新的UIAbility实例。运行时由UIAbility内部业务决定是否创建多实例

第一步:在module.json5文件中的"launchType"字段配置为"specified"。

TypeScript 复制代码
{
   "module": {
     ...
     "abilities": [
       {
         "launchType": "specified",
         ...
       }
     ]
  }
}

第二步:在调用startAbility()方法的want参数中,增加一个自定义参数来区别UIAbility实例,例如增加一个"instanceKey"自定义参数

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

let want = {
    deviceId: "", // deviceId为空表示本设备
    bundleName: "com.example.myapplication",
    abilityName: "MainAbility",
    moduleName: "device", // moduleName非必选,默认为当前UIAbility所在的Module
    parameters: { // 自定义信息
        instanceKey: getInstance(),
    },
}
// context为启动方UIAbility的AbilityContext
context.startAbility(want).then(() => {
    ...
}).catch((err) => {
    ...
})

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

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

    return '';
}
相关推荐
G_G#19 小时前
纯前端js插件实现同一浏览器控制只允许打开一个标签,处理session变更问题
前端·javascript·浏览器标签页通信·只允许一个标签页
@大迁世界19 小时前
TypeScript 的本质并非类型,而是信任
开发语言·前端·javascript·typescript·ecmascript
GIS之路19 小时前
GDAL 实现矢量裁剪
前端·python·信息可视化
是一个Bug19 小时前
后端开发者视角的前端开发面试题清单(50道)
前端
Amumu1213819 小时前
React面向组件编程
开发语言·前端·javascript
持续升级打怪中20 小时前
Vue3 中虚拟滚动与分页加载的实现原理与实践
前端·性能优化
GIS之路20 小时前
GDAL 实现矢量合并
前端
hxjhnct20 小时前
React useContext的缺陷
前端·react.js·前端框架
前端 贾公子20 小时前
从入门到实践:前端 Monorepo 工程化实战(4)
前端
菩提小狗20 小时前
Sqlmap双击运行脚本,双击直接打开。
前端·笔记·安全·web安全