当前位置:   article > 正文

鸿蒙开发最重要的概念:奇妙的UIAbility_鸿蒙 uiability(2)_uiability和 dataability之间的关系

uiability和 dataability之间的关系

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新HarmonyOS鸿蒙全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img

img
img
htt

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上鸿蒙开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip204888 (备注鸿蒙)
img

正文

UIAbility 是一种包含用户界面的应用组件,主要用于和用户进行交互。这里有个关键词:应用组件,既然是组件,那么一个APP应用就可以包含多个应用组件。

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

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

那什么是任务列表呢?

当你同时打开很多软件时,就可以看到一个任务列表,如下图所示:

一个应用可以有一个 UIAbility,也可以有多个 UIAbility,如下图所示。

例如,浏览器应用可以通过一个 UIAbility 结合多页面的形式让用户进行的搜索和浏览内容。

而聊天应用增加一个"外卖功能"的场景,则可以将聊天应用中"外卖功能"的内容独立为一个 UIAbility,当用户打开聊天应用的"外卖功能",查看外卖订单详情,此时有新的聊天消息,即可以通过最近任务列表切换回到聊天窗口继续进行聊天对话。

这样做的好处就是把功能解耦,进行一个模块一个模块的管理,这样极大的提高了项目的可维护性。

对于一个 UIAbility 来说,通常是对应于多个页面。建议将一个独立的功能模块放到一个UIAbility中,以多页面的形式呈现。例如新闻应用在浏览内容的时候,可以进行多页面的跳转使用。

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

UIAbility 的数据传递包括有 UIAbility 内页面的跳转和数据传递、UIAbility间的数据跳转和数据传递,本文主要讲解 UIAbility 内页面的跳转和数据传递。

在一个应用只包含一个 UIAbility 的场景下,可以通过新建多个页面来实现和丰富应用的内容。这会涉及到 UIAbility 内页面的新建以及 UIAbility 内页面的跳转和数据传递。

打开DevEco Studio,选择一个Empty Ability工程模板,创建一个工程,例如命名为MyApplication

  • src/main/ets/entryability目录下,初始会生成一个 UIAbility 文件EntryAbility.ts。可以在 EntryAbility.ts 文件中根据业务需要实现 UIAbility 的生命周期回调内容。
  • src/main/ets/pages目录下,会生成一个 Index 页面。这也是基于 UIAbility 实现的应用的入口页面。可以在Index页面中根据业务需要实现入口页面的功能。
  • src/main/ets/pages目录下,右键 New->Page,新建一个Second页面,用于实现页面间的跳转和数据传递。

为了实现页面的跳转和数据传递,需要新建一个页面。在原有 Index 页面的基础上,新建一个页面,例如命名为 Second.ets。

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

通过页面路由模块,可以使用不同的 url 访问不同的页面,包括跳转到 UIAbility 内的指定页面、用UIAbility 内的某个页面替换当前页面、返回上一页面或指定的页面等。

页面跳转

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

import router from ‘@ohos.router’;

页面跳转的几种方式,根据需要选择一种方式跳转即可。

方式一:router.pushUrl()方法

router.pushUrl({
url: ‘pages/Second’,
params: {
src: ‘Index页面传来的数据’,
}
}, router.RouterMode.Single)

方式二:router.replaceUrl()方法

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

这两个函数都可以用来页面跳转,区别在于

  • router.pushUrl():会将一个新的页面推到页面栈的顶部,而旧页面依然存在,如果按下返回键或者调用router.back(),旧页面会回到栈顶。
  • router.replaceUrl():会把当前旧页面用新页面来代替,旧页面会被销毁,如果按下返回键或者调用router.back(),不会回到旧页面。

API9及以上,两个方法都新增了 mode 参数,可以将mode参数配置为 router.RouterMode.Single 单实例模式和 router.RouterMode.Standard 多实例模式。

router.RouterMode.Standard为跳转的默认模式,可不写,表示每次都新建一个页面实例,即使已经存在相同url页面实例,如果使用router.pushUrl + router.RouterMode.Standard则会不断新增页面实例。很明显,将已经存在的实例重复创建是一件很消耗内存的事情,所以在这种需要再一次打开栈里面已经存在的实例的场景中,我们还是比较推荐使用Single模式。

router.RouterMode.Single则表示单例模式,如果栈里面已经存在该页面实例,在启动它的时候会直接从栈里面回到栈顶。

参数接收

已经实现了页面的跳转,接下来,在Second页面中如何进行自定义参数的接收呢?

可以先看下pushUrl里面第一个参数RouterOption里面都有哪些属性:

image.png

第二个参数 params 就是页面跳转中携带的参数,可以看到是一个Object,所以如果我们想传一个字符串到下一个页面,就不能直接将一个 string 给到 params,得这样做

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

在params 里面以一个key-value形式传递参数,而在新页面里面,通过传递过来的key把对应值取出来,在下一个页面获取参数的代码是这样写的:

import router from ‘@ohos.router’;

@Entry
@Component
struct Second {
@State src: string = (router.getParams() as Record<string, string>)[‘src’];
// 页面刷新展示

}

页面返回

在Second页面中,可以通过调用router.back()方法实现返回到上一个页面,或者在调用router.back()方法时增加可选的options参数(增加url参数)返回到指定页面。

  • 调用router.back()返回的目标页面需要在页面栈中存在才能正常跳转。
  • 例如调用router.pushUrl()方法跳转到Second页面,在Second页面可以通过调用router.back()方法返回到上一个页面。
  • 例如调用router.clear()方法清空了页面栈中所有历史页面,仅保留当前页面,此时则无法通过调用router.back()方法返回到上一个页面。

注意:如果返回页与指定页面之间存在若干页面,那么指定页面被推到栈顶,返回页与中间的若干页面会被销毁

返回时添加询问弹窗

主要是在一些重要页面里面,比如支付页面,或者一些信息填写页面里面,用户在未保存或者提交当前页面的信息时就点击了返回按钮,页面中会弹出个询问框来让用户二次确认是否要进行返回操作。

询问框可以是系统弹框,也可以是自定义弹框。

系统弹框可以使用router.showAlertBeforeBackPage去实现,这个函数里面接收的参数为EnableAlertOptions,这个类里面只有一个message属性,用来在弹框上显示文案。

使用方式如下,在router.back()操作之前,调用一下router.showAlertBeforeBackPage,弹框上会有确定和取消两个按钮,点击取消关闭弹窗停留在当前页面,点击确定就执行router.back()操作。

但是如果想要更改下按钮文案,或者顺序,或者自定义按钮的点击事件,就不能用系统弹框了,得使用自定义询问框。

自定义询问框使用promptAction.showDialog,在showDialog里面接收的参数为showDialogOptions,可以看下这个类里面有哪些属性:

可以看到比系统弹框那边多了两个属性,能够设置弹框标题的title以及按钮buttons,可以看到buttons是一个Button的数组,最多可以设置三个按钮,注意这个Button并不是我们熟悉的Button组件,它内部只支持自定义文案以及颜色

可以看到弹框上面就多了一个标题,以及按钮的文案与颜色也变了。

那么如何设置点击事件呢?

现在两个按钮点了除了关闭按钮之外是没有别的操作的,如果想要添加其他操作,就需要通过then操作符进行,在then里面会拿到一个ShowDialogSuccessResponse,这个类里面只有一个index属性,这个index就表示按钮的下标,可以通过判断下标来给指定按钮添加事件,代码如下:

UIAbility的生命周期

当用户浏览、切换和返回到对应应用的时候,应用中的 UIAbility 实例会在其生命周期的不同状态之间转换。

UIAbility 类提供了很多回调,通过这些回调可以知晓当前 UIAbility 的某个状态已经发生改变:例如 UIAbility 的创建和销毁,或者 UIAbility 发生了前后台的状态切换。

例如从桌面点击图库应用图标,到启动图库应用,应用的状态经过了从创建到前台展示的状态变化。如下图所示,从桌面点击图库应用图标启动应用。

回到桌面,从最近任务列表,切换回到图库应用,应用的状态经过了从后台到前台展示的状态变化。如下图所示,从最近任务列表切换回到图库应用。

在UIAbility的使用过程中,会有多种生命周期状态。掌握UIAbility的生命周期,对于应用的开发非常重要。

为了实现多设备形态上的裁剪和多窗口的可扩展性,系统对组件管理和窗口管理进行了解耦。UIAbility的生命周期包括Create、Foreground、Background、Destroy四个状态,WindowStageCreateWindowStageDestroy 为窗口管理器(WindowStage)在UIAbility中管理UI界面功能的两个生命周期回调,从而实现UIAbility与窗口之间的弱耦合。

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

import UIAbility from ‘@ohos.app.ability.UIAbility’;
import window from ‘@ohos.window’;

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

}

}

例如,用户打开电池管理应用,在应用加载过程中,在UI页面可见之前,可以在onCreate回调中读取当前系统的电量情况,用于后续的UI页面展示。

  • UIAbility实例创建完成之后,在进入Foreground之前,系统会创建一个WindowStage。每一个UIAbility实例都对应持有一个WindowStage实例。WindowStage为本地窗口管理器,用于管理窗口相关的内容,例如与界面相关的获焦/失焦、可见/不可见。

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

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) => {

});
}

}

例如,用户打开游戏应用,正在打游戏的时候,有一个消息通知,打开消息,消息会以弹窗的形式弹出在游戏应用的上方,此时,游戏应用就从获焦切换到了失焦状态,消息应用切换到了获焦状态对于消息应用,在onWindowStageCreate回调中,会触发获焦的事件回调,可以进行设置消息应用的背景颜色、高亮等操作

  • Foreground和Background状态,分别在UIAbility切换至前台或者切换至后台时触发。分别对应于onForeground回调和onBackground回调。

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

}

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

}
}

例如,用户打开地图应用查看当前地理位置的时候,假设地图应用已获得用户的定位权限授权。在UI页面显示之前,可以在onForeground回调中打开定位功能,从而获取到当前的位置信息。

当地图应用切换到后台状态,可以在onBackground回调中停止定位功能,以节省系统的资源消耗。

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

import UIAbility from ‘@ohos.app.ability.UIAbility’;
import window from ‘@ohos.window’;

export default class EntryAbility extends UIAbility {

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

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注鸿蒙)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

;
import window from ‘@ohos.window’;

export default class EntryAbility extends UIAbility {

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

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注鸿蒙)
[外链图片转存中…(img-bqFf5Zyb-1713221300302)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

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

闽ICP备14008679号