1# 使用UI上下文接口操作界面(UIContext) 2 3## 概述 4 5OpenHarmony支持Stage模型后,存在一个ArkTS引擎里面运行多个ArkUI实例的场景。此时,一个ArkTS引擎下可能会有多个Ability,每个Ability可能有多个Window,每个Window通过loadContent加载页面,生成一个UIContent(ArkUI实例)。 6 7**图1** 多实例关系图 8 9 10FA模型默认只支持一个ArkUI实例,没有多实例的场景。当框架切换到Stage模型后,在FA模型下开放的ArkUI全局接口,在调用时无法明确运行在哪个实例里,存在语义不明确的问题。并且,这些接口实现依赖了ArkUI实例相关的信息,如果实例不明确,会导致运行时会出现预期外的行为。 11 12为了解决此类问题,ArkUI针对Stage模型推出了替代接口,以便满足开发者在多实例场景下的诉求。可使用window的接口方法[getUIContext](../reference/apis-arkui/js-apis-window.md#getuicontext10)或者使用组件内置方法[getUIContext](../reference/apis-arkui/arkui-ts/ts-custom-component-api.md#getuicontext)直接获取当前组件所在的UIContext,并使用[UIContext](../reference/apis-arkui/js-apis-arkui-UIContext.md#uicontext)中对应的接口获取与实例绑定的对象。 13 14## 接口替代关系 15 16部分多实例替代接口如下表所示,UIContext实例支持的全量接口以[UIContext](../reference/apis-arkui/js-apis-arkui-UIContext.md)中描述为准。 17 18| 全局接口 | 替代接口 | 说明 | 19| :-----------------------------------: | :-----------------------------------: | :------------------------: | 20| @ohos.animator | createAnimator | 自定义动画控制器 | 21| @ohos.arkui.componentSnapshot | getComponentSnapshot | 组件截图 | 22| @ohos.arkui.componentUtils | getComponentUtils | 组件工具类 | 23| @ohos.arkui.dragController | getDragController | 拖拽控制器 | 24| @ohos.arkui.inspector | getUIInspector | 组件布局回调 | 25| @ohos.arkui.observer | getUIObserver | 无感监听 | 26| @ohos.font | getFont | 自定义字体 | 27| @ohos.measure | getMeasureUtil | 文本计算 | 28| @ohos.mediaquery | getMediaQuery | 媒体查询 | 29| @ohos.promptAction | getPromptAction | 弹窗 | 30| @ohos.router | getRouter | 页面路由 | 31| AlertDialog | showAlertDialog | 警告弹窗 | 32| ActionSheet | showActionSheet | 列表选择弹窗 | 33| CalendarPickerDialog | 不支持 | 日历选择器弹窗 | 34| DatePickerDialog | showDatePickerDialog | 日期滑动选择弹窗 | 35| TimePickerDialog | showTimePickerDialog | 时间滑动选择器弹窗 | 36| TextPickerDialog | showTextPickerDialog | 文本滑动选择器弹窗 | 37| ContextMenu | getContextMenuController | 菜单控制 | 38| vp2px/px2vp/fp2px/px2fp/lpx2px/px2lpx | vp2px/px2vp/fp2px/px2fp/lpx2px/px2lpx | 像素单位转换 | 39| focusControl | getFocusControl | 焦点控制 | 40| cursorControl | getCursorControl | 光标控制 | 41| getContext | getHostContext | 获取当前的Ability的Context | 42| LocalStorage.getShared | getSharedLocalStorage | 获取Ability传递的Storage | 43| animateTo | animateTo | 显式动画 | 44| animateToImmediately | 不支持 | 显式立即动画 | 45 46## 接口切换方法 47 48下述示例,实现了在具体窗口内弹出Toast。ArkUI可感知到是在当前页面下调用,找到对应的UI实例。但是,如果一些复杂场景的起始调用不在页面中,经过了异步调用,作用的实例就可能出现行为不明确的问题。 49 50<!--deprecated_code_no_check--> 51```ts 52import { promptAction } from '@kit.ArkUI' 53 54@Entry 55@Component 56struct Index { 57 build() { 58 Row() { 59 Button() 60 .onClick(() => { 61 promptAction.showToast({ 62 message: 'Message Info', 63 duration: 2000 64 }); 65 }) 66 } 67 } 68} 69``` 70下述示例,callNative是Node-API方法,回调如果是由C侧异步触发,执行时无法感知当前页面信息,无法确定响应的UI实例。 71 72<!--deprecated_code_no_check--> 73```ts 74import { promptAction } from '@kit.ArkUI' 75 76@Entry 77@Component 78struct Index { 79 build() { 80 Row() { 81 Button() 82 .onClick(() => { 83 bridge.callNative("xxxx", ()=> { 84 promptAction.showToast({ 85 message: 'Message Info', 86 duration: 2000 87 }); 88 }) 89 }) 90 } 91 } 92} 93``` 94 95针对上述问题,可使用组件内置方法[`getUIContext`](../reference/apis-arkui/arkui-ts/ts-custom-component-api.md#getuicontext)直接获取当前组件所在的UIContext,并使用[UIContext](../reference/apis-arkui/js-apis-arkui-UIContext.md#uicontext)中的getPromptAction接口获取与实例绑定的对象,使得Toast绑定到具体的实例。 96```ts 97@Entry 98@Component 99struct Index { 100 build() { 101 Row() { 102 Button() 103 .onClick(() => { 104 let uiContext = this.getUIContext(); 105 let prompt = uiContext.getPromptAction(); 106 bridge.callNative("xxxx", ()=> { 107 prompt.showToast({ 108 message: 'Message Info', 109 duration: 2000 110 }); 111 }) 112 }) 113 } 114 } 115} 116``` 117 118对于UIContext中没有提供替代的接口(例如,CalendarPickerDialog和animateToImmediately),或者开发者自定义实现的业务行为与多实例相关,需要和实例绑定时(例如,一个代码段),可以使用[UIContext](../reference/apis-arkui/js-apis-arkui-UIContext.md#uicontext)的runScopedTask方法将接口或一段代码段包裹起来。 119 120| UIContext接口 | 说明 | 121| ------------- | -------------------- | 122| runScopedTask | 执行绑定实例的闭包。 | 123 124上文的示例也可以使用如下方法实现。 125 126<!--deprecated_code_no_check--> 127```ts 128// 执行绑定实例的闭包 129import { promptAction } from '@kit.ArkUI' 130 131@Entry 132@Component 133struct Index { 134 build() { 135 Row() { 136 Button() 137 .onClick(() => { 138 let uiContext = this.getUIContext(); 139 uiContext.runScopedTask(() => { 140 promptAction.showToast({ 141 message: 'Message Info', 142 duration: 2000 143 }); 144 }) 145 }) 146 } 147 } 148} 149``` 150