鸿蒙中存在一些无感监听,这些监听经过系统API封装使用很简单,但是对实际业务开发中有很重要,例如埋点业务、数据统计、行为上报、切面拦截等。
Navigation的页面切换
在鸿蒙中Navigation被用来作为路由栈进行页面跳转,如果你想知道页面的路由栈,以及前后切换的页面,可以通过官方提供的无感监听的页面切换navDestinationSwitch。
private _navDestinationListener() {this.uiContext?.getUIObserver().on('navDestinationSwitch', (info: uiObserver.NavDestinationSwitchInfo) => {let to = info.to;if (to != 'navBar') {let navName = `${to.name.toString()}#${to.navDestinationId}`;}});}
this.uiContext?.getUIObserver().off('navDestinationSwitch');
点击事件的监听
通过对系统控件设置customProperty,可以通过didClick进行点击事件拦截,相当于对全部的系统控件可以hook处理。
@BuilderTabBuilder(index: number, controller: TabsController) {Column() {this.CanvasComponent(index, this.getCanvasRenderingContext())}.onClick(() => {}).layoutWeight(1).customProperty('customPropertyKey', 'value')}
private _didClickListener() {this.uiContext?.getUIObserver().on('didClick', (event: GestureEvent, frameNode?: FrameNode) => {if (frameNode == null) {return;}frameNode.getCustomProperty('customPropertyKey')});}
this.uiContext?.getUIObserver().off('didClick');
�
监听TabContent页面的切换事件
在鸿蒙中页签Tabs控件的使用频率比较高,如果想知道哪个子TabContent被点击了,就可以使用监听TabContent页面的切换事件。
private _tabContentUpdateListener() {this.uiContext?.getUIObserver().on('tabContentUpdate', (info: uiObserver.TabContentInfo) => {if (info.state != uiObserver.TabContentState.ON_SHOW) {return;}this._handleContentUpdateEvent(info.id, info.uniqueId, info.index, info.tabContentUniqueId, true);let frameNode = this.uiContext?.getFrameNodeByUniqueId(info.tabContentUniqueId);});}
this.uiContext?.getUIObserver().off('tabContentUpdate');

Aspect插桩能力
Aspect类用于封装提供切面能力(Aspect Oriented Programming,简写AOP)的接口,这些接口可以用来对类方法进行前后插桩或者替换实现。
在指定的类对象的原方法执行前插入一个函数。addBefore接口执行完成后,都会先执行插入的函数逻辑,再执行指定类对象的原方法。
在指定的类方法执行后插入一段逻辑。最终返回值是插入函数执行后的返回值。
通过插桩处理,在弹框前后做一些逻辑,例如在弹框前后设置变量,就可以判断弹框是否有触发。
util.Aspect.addBefore(CustomDialogController, 'open', false, () => {AppStorage.setOrCreate(BusinessUseConstant.CUSTOMDIALOG_ISOPEN, true)});util.Aspect.addBefore(CustomDialogController, 'close', false, () => {AppStorage.setOrCreate(BusinessUseConstant.CUSTOMDIALOG_ISOPEN, false)});