「鸿蒙」应用程序入口-UIAbility
UIAbility是一种蕴含用户界面的利用组件,次要用于和用户进行交互。UIAbility也是系统调度的单元,为利用提供窗口在其中绘制界面。
每一个UIAbility实例,都对应于一个最近工作列表中的工作。
一个利用能够有一个UIAbility,也能够有多个UIAbility,如下图所示。例如浏览器利用能够通过一个UIAbility联合多页面的模式让用户进行的搜寻和浏览内容;而聊天利用减少一个“外卖性能”的场景,则能够将聊天利用中“外卖性能”的内容独立为一个UIAbility,当用户关上聊天利用的“外卖性能”,查看外卖订单详情,此时有新的聊天音讯,即能够通过最近工作列表切换回到聊天窗口持续进行聊天对话。
一个UIAbility能够对应于多个页面,倡议将一个独立的功能模块放到一个UIAbility中,以多页面的模式出现。例如新闻利用在浏览内容的时候,能够进行多页面的跳转应用。
UIAbility内页面的跳转和数据传递
UIAbility的数据传递包含有UIAbility内页面的跳转和数据传递、UIAbility间的数据跳转和数据传递。
页面间的导航能够通过页面路由router模块来实现。页面路由模块依据页面url找到指标页面,从而实现跳转。通过页面路由模块,能够应用不同的url拜访不同的页面,包含跳转到UIAbility内的指定页面、用UIAbility内的某个页面替换以后页面、返回上一页面或指定的页面等。具体应用办法请参见ohos.router (页面路由)。
页面跳转和参数接管
在应用页面路由之前,须要先导入router模块,如下代码所示。
import router from '@ohos.router';
页面跳转的几种形式,依据须要抉择一种形式跳转即可。
- 形式一:API9及以上,router.pushUrl() 办法新增了mode参数,能够将mode参数配置为 router.RouterMode.Single单实例模式 和 router.RouterMode.Standard多实例模式。
在单实例模式下:如果指标页面的url在页面栈中曾经存在同url页面,离栈顶最近同url页面会被挪动到栈顶,挪动后的页面为新建页,原来的页面依然存在栈中,页面栈的元素数量不变;如果指标页面的url在页面栈中不存在同url页面,按多实例模式跳转,页面栈的元素数量会加1。
阐明
当页面栈的元素数量较大或者超过32时,能够通过调用router.clear()办法革除页面栈中的所有历史页面,仅保留以后页面作为栈顶页面。
router.pushUrl({ url: 'pages/Second', params: { src: 'Index页面传来的数据', }}, router.RouterMode.Single)
形式二:API9及以上,router.replaceUrl() 办法新增了mode参数,能够将mode参数配置为 router.RouterMode.Single单实例模式 和 router.RouterMode.Standard多实例模式。
在单实例模式下:如果指标页面的url在页面栈中曾经存在同url页面,离栈顶最近同url页面会被挪动到栈顶,替换以后页面,并销毁被替换的以后页面,挪动后的页面为新建页,页面栈的元素数量会减1;如果指标页面的url在页面栈中不存在同url页面,按多实例模式跳转,页面栈的元素数量不变。router.replaceUrl({url: 'pages/Second',params: { src: 'Index页面传来的数据',}}, router.RouterMode.Single)
曾经实现了页面的跳转,接下来,在Second页面中如何进行自定义参数的接管呢?
通过调用 router.getParams() 办法获取Index页面传递过去的自定义参数。
import router from '@ohos.router';@Entry@Componentstruct Second { @State src: string = router.getParams()?.['src']; // 页面刷新展现 ...}
成果示意如下图所示。在Index页面中,点击“Next”后,即可从Index页面跳转到Second页面,并在Second页面中接管参数和进行页面刷新展现。
页面返回和参数接管
常常还会遇到一个场景,在Second页面中,实现了一些性能操作之后,心愿能返回到Index页面,那咱们要如何实现呢?
在Second页面中,能够通过调用 router.back() 办法实现返回到上一个页面,或者在调用router.back()办法时减少可选的options参数(减少url参数)返回到指定页面。
阐明
- 调用router.back()返回的指标页面须要在页面栈中存在能力失常跳转。
- 例如调用router.pushUrl()办法跳转到Second页面,在Second页面能够通过调用router.back()办法返回到上一个页面。
- 例如调用router.clear()办法清空了页面栈中所有历史页面,仅保留以后页面,此时则无奈通过调用router.back()办法返回到上一个页面。
返回上一个页面。
router.back();
返回到指定页面。
router.back({ url: 'pages/Index' });
成果示意如下图所示。在Second页面中,点击“Back”后,即可从Second页面返回到Index页面。
页面返回能够依据业务须要减少一个询问对话框。
即在调用router.back()办法之前,能够先调用router.enableBackPageAlert()办法开启页面返回询问对话框性能。
阐明
- router.enableBackPageAlert() 办法开启页面返回询问对话框性能,只针对以后页面失效。例如在调用router.pushUrl()或者router.replaceUrl()办法,跳转后的页面均为新建页面,因而在页面返回之前均须要先调用router.enableBackPageAlert()办法之后,页面返回询问对话框性能才会失效。
- 如需敞开页面返回询问对话框性能,能够通过调用 router.disableAlertBeforeBackPage() 办法敞开该性能即可。
router.enableBackPageAlert({ message: 'Message Info'});router.back();
在Second页面中,调用router.back()办法返回上一个页面或者返回指定页面时,依据须要持续减少自定义参数,例如在返回时减少一个自定义参数src。
router.back({ url: 'pages/Index', params: { src: 'Second页面传来的数据', }})
从Second页面返回到Index页面。在Index页面通过调用router.getParams()办法,获取Second页面传递过去的自定义参数。
阐明
调用router.back()办法,不会新建页面,返回的是原来的页面,在原来页面中@State申明的变量不会反复申明,以及也不会触发页面的aboutToAppear()生命周期回调,因而无奈间接在变量申明以及页面的aboutToAppear()生命周期回调中接管和解析router.back()传递过去的自定义参数。
能够放在业务须要的地位进行参数解析。示例代码在Index页面中的onPageShow()生命周期回调中进行参数的解析。
import router from '@ohos.router';@Entry@Componentstruct Index { @State src: string = ''; onPageShow() { this.src = router.getParams()?.['src']; } // 页面刷新展现 ...}
成果示意图如下图所示。在Second页面中,点击“Back”后,即可从Second页面返回到Index页面,并在Index页面中接管参数和进行页面刷新展现。
UIAbility的生命周期
当用户浏览、切换和返回到对应利用的时候,利用中的UIAbility实例会在其生命周期的不同状态之间转换。
UIAbility类提供了很多回调,通过这些回调能够通晓以后UIAbility的某个状态曾经产生扭转:例如UIAbility的创立和销毁,或者UIAbility产生了前后台的状态切换。
为了实现多设施状态上的裁剪和多窗口的可扩展性,系统对组件治理和窗口治理进行理解耦。UIAbility的生命周期包含Create、Foreground、Background、Destroy四个状态,WindowStageCreate和WindowStageDestroy为窗口管理器(WindowStage)在UIAbility中治理UI界面性能的两个生命周期回调,从而实现UIAbility与窗口之间的弱耦合。如下图所示。
Create
Create状态,在UIAbility实例创立时触发,零碎会调用onCreate回调。能够在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接口设置利用要加载的页面,Window接口的应用详见窗口开发领导。
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
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回调中进行定位性能,以节俭零碎的资源耗费。
WindowStageDestroy
对应于onWindowStageCreate回调。在UIAbility实例销毁之前,则会先进入onWindowStageDestroy回调,咱们能够在该回调中开释UI页面资源。
import UIAbility from '@ohos.app.ability.UIAbility';import window from '@ohos.window';export default class EntryAbility extends UIAbility { ... onWindowStageDestroy() { // 开释UI页面资源 ... }}
例如在onWindowStageCreate中设置的获焦/失焦等WindowStage订阅事件。
Destroy
Destroy状态,在UIAbility销毁时触发。能够在onDestroy回调中进行系统资源的开释、数据的保留等操作。
import UIAbility from '@ohos.app.ability.UIAbility';import window from '@ohos.window';export default class EntryAbility extends UIAbility { ... onDestroy() { // 系统资源的开释、数据的保留等 ... }}
例如用户应用利用的程序退出性能,会调用UIAbilityContext的terminalSelf()办法,从而实现UIAbility销毁。或者用户应用最近工作列表敞开该UIAbility实例时,也会实现UIAbility的销毁。
UIAbility的启动模式
对于浏览器或者新闻等利用,用户在关上该利用,并浏览拜访相干内容后,回到桌面,再次关上该利用,显示的依然是用户以后拜访的界面。
对于利用的分屏操作,用户心愿应用两个不同利用(例如备忘录利用和图库利用)之间进行分屏,也心愿能应用同一个利用(例如备忘录利用本身)进行分屏。
对于文档利用,用户从文档利用中关上一个文档内容,回到文档利用,持续关上同一个文档,心愿关上的还是同一个文档内容。
基于以上场景的思考,UIAbility以后反对3种启动模式:
- singleton(单实例模式)
- multiton(多实例模式)
- specified(指定实例模式)
对启动模式的具体阐明如下:
singleton(单实例模式)
当用户关上浏览器或者新闻等利用,并浏览拜访相干内容后,回到桌面,再次关上该利用,显示的依然是用户以后拜访的界面。
这种状况下能够将UIAbility配置为singleton(单实例模式)。每次调用startAbility()办法时,如果利用过程中该类型的UIAbility实例曾经存在,则复用零碎中的UIAbility实例,零碎中只存在惟一一个该UIAbility实例。
即在最近工作列表中只存在一个该类型的UIAbility实例。
singleton启动模式,也是默认状况下的启动模式。
singleton启动模式,每次调用startAbility()启动UIAbility时,如果利用过程中该类型的UIAbility实例曾经存在,则复用零碎中的UIAbility实例,零碎中只存在惟一一个该UIAbility实例。
singleton启动模式的开发应用,在module.json5文件中的“launchType”字段配置为“singleton”即可。
{ "module": { ... "abilities": [ { "launchType": "singleton", ... } ] }}
multiton(多实例模式)
用户在应用分屏性能时,心愿应用两个不同利用(例如备忘录利用和图库利用)之间进行分屏,也心愿能应用同一个利用(例如备忘录利用本身)进行分屏。
这种状况下能够将UIAbility配置为multiton(多实例模式)。每次调用startAbility()办法时,都会在利用过程中创立一个该类型的UIAbility实例。
即在最近工作列表中能够看到有多个该类型的UIAbility实例。
multiton启动模式,每次调用startAbility()办法时,都会在利用过程中创立一个该类型的UIAbility实例。
multiton启动模式的开发应用,在module.json5文件中的“launchType”字段配置为“multiton”即可。
{ "module": { ... "abilities": [ { "launchType": "multiton", ... } ] }}
specified(指定实例模式)
用户打开文档利用,从文档利用中关上一个文档内容,回到文档利用,持续关上同一个文档,心愿关上的还是同一个文档内容;以及在文档利用中新建一个新的文档,每次新建文档,心愿关上的都是一个新的空白文档内容。
这种状况下能够将UIAbility配置为specified(指定实例模式)。在UIAbility实例新创建之前,容许开发者为该实例创立一个字符串Key,新创建的UIAbility实例绑定Key之后,后续每次调用startAbility办法时,都会询问利用应用哪个Key对应的UIAbility实例来响应startAbility申请。如果匹配有该UIAbility实例的Key,则间接拉起与之绑定的UIAbility实例,否则创立一个新的UIAbility实例。运行时由UIAbility外部业务决定是否创立多实例。
specified启动模式,依据业务须要是否创立一个新的UIAbility实例。在UIAbility实例创立之前,会先进入AbilityStage的onAcceptWant回调,在onAcceptWant回调中为每一个UIAbility实例创立一个Key,后续每次调用startAbility()办法创立该类型的UIAbility实例都会询问应用哪个Key对应的UIAbility实例来响应startAbility()申请。
specified启动模式的开发应用的步骤如下所示。
在module.json5文件中的“launchType”字段配置为“specified”。
{"module": { ... "abilities": [ { "launchType": "specified", ... } ] }}
在调用startAbility()办法的want参数中,减少一个自定义参数来区别UIAbility实例,例如减少一个“instanceKey”自定义参数。
// 在启动指定实例模式的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的AbilityContextcontext.startAbility(want).then(() => { ...}).catch((err) => { ...})
在被拉起方UIAbility对应的AbilityStage的onAcceptWant生命周期回调中,解析传入的want参数,获取“instanceKey”自定义参数。依据业务须要返回一个该UIAbility实例的字符串Key标识。如果之前启动过此Key标识的UIAbility,则会将之前的UIAbility拉回前台并获焦,而不创立新的实例,否则创立新的实例并启动。
onAcceptWant(want): string { // 在被启动方的AbilityStage中,针对启动模式为specified的UIAbility返回一个UIAbility实例对应的一个Key值 // 以后示例指的是device Module的EntryAbilityif (want.abilityName === 'MainAbility') { return `DeviceModule_MainAbilityInstance_${want.parameters.instanceKey}`; } return '';}
例如在文档利用中,能够对不同的文档实例内容绑定不同的Key值。当每次新建文档的时候,能够传入不同的新Key值(如能够将文件的门路作为一个Key标识),此时AbilityStage中启动UIAbility时都会创立一个新的UIAbility实例;当新建的文档保留之后,回到桌面,或者新关上一个已保留的文档,回到桌面,此时再次关上该已保留的文档,此时AbilityStage中再次启动该UIAbility时,关上的依然是之前原来已保留的文档界面。
参考
- https://developer.huawei.com/consumer/cn/training/course/slig...