【鸿蒙应用ArkTS开发系列】- Har包中子组件中监听生命周期实现

文章目录

  • 前言
  • 解决思路
    • 1. 集成方定义壳页面
    • 2. 生命函数钩子函数
      • 1. 壳页面调用生命周期函数
      • 2. 子组件进行生命周期函数处理方法注入
  • 总结

前言

在鸿蒙应用开发中,有时候我们会创建HAR 模块封装一些SDK能力提供给第三方APP进行集成。
鸿蒙的har 包并不支持定义page页面对外导出,也不支持配置路由信息,因此我们多是在har包中提供组件,通过导出组件的形式,提供给App引用使用。
在鸿蒙中,非@Entry装饰的组件,只能收到如下生命周期函数的回调

  • aboutToAppear?(): void;
  • aboutToDisappear?(): void;

对于页面级组件来说,就可以收到

  • onPageShow?(): void;
  • onPageHide?(): void;
  • onBackPress?(): void;

但是在实际使用过程中,如果我们的har包中想提供跟页面组件一样的功能,受限于har限制,不能定义为@Entry 组件,因而无法接收到上述三个函数的回调,实际功能会收到限制。那有没有办法解决上述问题呢?

解决思路

1. 集成方定义壳页面

我们在har模块中定义一个子组件,pages/SdkPage.ets

@Component
export struct SdkPage {build() {
...
}}

在App中定义壳页面,pages/SdkPageShell.ets
这里也可以创建一个HSP对外提供,壳页面配置在HSP包中,对外提供HSP给App集成(这个HSP的,后面有时间在单独写一篇进行讲解SDK的封装,有兴趣的可以私信我或者评论区留言)。

@Entry
@Component
export struct SdkPageShell {build() {Column() {SdkPage()}.width('100%').height('100%')}
}

套娃模式,这样我们就能将har包中的子组件作为页面级别进行展示了。App需要对SdkPageShell进行页面路由配置。
SdkPageShell 作为一个空壳页面。
但是在实际开发中,就会出现正文前言提到的问题,有部分生命周期函数无法收到回调, 导致我们开发页面功能时处处受限,比如页面隐藏时进行一些消息取消订阅,页面显示时进行消息订阅,如果是要做编辑功能,希望是用户在触发手机实体键的时候,弹窗询问用户是否进行数据保存,不能收到
onBackPress回调,那功能就无法实现了。
那应该怎么做呢,接着往下看。

2. 生命函数钩子函数

经过对子组件的个追踪,发现 在子组件中,是能够获取到父组件的实例的parent_,那我们就可以对其进行一点点的处理。如果我们的子组件是页面组件下的一级子组件,那this[‘parent_’] 拿到的就是上文提到的壳页面SdkPageShell ,
parent_无法直接获取到,我们通过this[‘parent_’] 就可以拿到实例。
那这里有一个思路,我们对this[‘parent_’] 进行一个生命周期函数的方法注入。

在SdkPage.ets中,

 aboutToAppear() {this['parent_'].onBackPress= this.onBackPress.bind(this);};onBackPress() {Logger.info(this.TAG, 'onBackPress is called');return true;}

既然按实体返回键的时候,系统会回调壳页面的onBackPress函数,在壳页面中重写onBackPress就可以收到回调, 那我们这里给壳页面注入一个onBackPress进行替换,然后绑定到SdkPage子组件上的onBackPress中去,这样是不是就可以收到回调呢?按这个思路好像是行得通,那就运行试试看,可是很遗憾不能生效。原因是我们改动的是运行期壳页面的onBackPress方法,系统触发实际调用的是CustomComponent的onBackPress。
那壳页面重写onBackPress是能够收到回调,那在壳页面进行一点修改不就可以了,

1. 壳页面调用生命周期函数

在SdkPageShell.ets中,

@Entry
@Component
export struct SdkPageShell {build() {Column() {SdkPage()}.width('100%').height('100%')}onBackPress() {if (this['onBackPressHook']) {return this['onBackPressHook'].call(this);}}
}
  1. 重写onBackPress方法
  2. 判断是否有onBackPressHook方法,如果有,触发onBackPressHook,根据onBackPressHook返回值确认是否拦截返回
  3. 如果没有定义onBackPressHook,就直接不处理

看到这里,会不会有点懵,onBackPressHook是啥,SdkPageShell中并未定义onBackPressHook,这里的代码能生效吗,相信有的同学已经反应过来,没错,我们要到子组件中对SdkPageShell进行 onBackPressHook方法的注入。

2. 子组件进行生命周期函数处理方法注入

这里贴下完整代码:

在SdkPage.ets中,

@Component
export struct SdkPage {build() {...}aboutToAppear() {this.addEvent();};aboutToDisappear() {}addEvent() {this['parent_'].onBackPressHook= this.onBackPress.bind(this);}onBackPress() {Logger.info(this.TAG, 'onBackPress is called');this.handlePageBack();return true;}
}

这样,在按了手机的物理返回键的时候,子组件SdkPage 就能在onBackPress中收到回调,在handlePageBack中进行返回事件处理,比如弹窗提供用户进行数据保存, return true意思是要拦截系统返回,这样页面就不会被关闭。

总结

其他的生命周期函数,处理方式跟上述的方式一致,总结思路如下:

  1. 壳页面在触发生命周期函数回调时,调用生命周期函数处理函数(需判断是否有定义)
  2. 子组件给壳页面注入生命周期函数处理函数,绑定到自身的方法中。

上述方法,只需要App配合,写少量代码,在壳页面中进行生命周期函数的调用,或者是SDK提供方提供壳页面给到App。如果觉得这样还是不够简洁,那就得考虑提供HSP包给App集成,而不是提供HAR包,这样就可以直接提供Page而不是提供组件。 上面方案也只是一个实现的思路之一,也是有其局限性,比如多个子组件的情况下,就会存在多注入覆盖的问题,因此需要根据实际开发情况来选择实现方案,本文这里仅提供一种实现思路,如果有其他实现方式,欢迎评论区探讨。谢谢阅读!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/15209.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【解惑笔记】树莓派+OpenCV+YOLOv5目标检测(Pytorch框架)

【学习资料】 子豪兄的零基础树莓派教程https://github.com/TommyZihao/ZihaoTutorialOfRaspberryPi/blob/master/%E7%AC%AC2%E8%AE%B2%EF%BC%9A%E6%A0%91%E8%8E%93%E6%B4%BE%E6%96%B0%E6%89%8B%E6%97%A0%E7%97%9B%E5%BC%80%E6%9C%BA%E6%8C%87%E5%8D%97.md#%E7%83%A7%E5%BD%95…

Flink - souce算子

水善利万物而不争,处众人之所恶,故几于道💦 目录 1. 从Java的集合中读取数据 2. 从本地文件中读取数据 3. 从HDFS中读取数据 4. 从Socket中读取数据 5. 从Kafka中读取数据 6. 自定义Source 官方文档 - Flink1.13 1. 从Java的集合中读取数据 …

更改anaconda自带的jupyter的工作目录

点击Anaconda Prompt 输入jupyter notebook --generate-config 生成jupyter 配置文件,会显示配置文件的具体目录,一般默认是在 C:\Users\admin\.jupyter\jupyter_notebook_config.py 打开jupyter_notebook_config.py配置文件, 搜索noteboo…

Vue 3:玩一下web前端技术(一)

前言 本章内容为VUE前端环境搭建与相关前端技术讨论。 下一篇文章地址: Vue 3:玩一下web前端技术(二)_Lion King的博客-CSDN博客 一、环境搭建 1. 安装Node.js Vue是基于Node.js的,因此首先需要安装Node.js。官网…

缓存数据同步技术Canal

说明:缓存数据同步,以Redis为例,如何保证从Redis中取出来的数据与MySQL中的一致?在微服务架构下,通常可以用以下两种技术来实现: MQ:在修改数据的同时,发送一个消息修改缓存&#x…

CSDNmarkdown编辑器文字颜色、大小、字体与背景色的设置

参考原文 007与狼共舞 https://blog.csdn.net/manjianchao/article/details/53668280 一、颜色 浅红色文字&#xff1a;<font color"#dd0000">浅红色文字</font> 深红色文字&#xff1a;<font color"#660000">深红色文字</font>…

Go Ethereum源码学习笔记 001 Geth Start

Go Ethereum源码学习笔记 前言[Chapter_001] 万物的起点: Geth Start什么是 geth&#xff1f;go-ethereum Codebase 结构 Geth Start前奏: Geth Consolegeth 节点是如何启动的NodeNode的关闭 Ethereum Backend附录 前言 首先读者需要具备Go语言基础&#xff0c;至少要通关菜鸟…

对象引用(强,软,弱,虚)

在JDK1.2之前&#xff0c;一个对象只有两种状态"已被引用"和"未被引用" &#xff0c;在JDK1.2后&#xff0c;为了使得程序能够更好的控制对象的生命周期&#xff0c;引入了对象特殊状态的四种引用&#xff0c;由强到弱分别是&#xff1a;强引用&#xff0c…

怎么维护自己的电脑?

方向一&#xff1a;我的电脑介绍 我使用的是一台来自知名品牌的笔记本电脑。它具有高性能的核心配置&#xff0c;如快速处理器、大容量内存和高性能显卡&#xff0c;以及宽敞的存储空间。我选择这台电脑主要是因为它的出色性能和可靠性&#xff0c;能够满足我在学习和工作中的…

【wsl-windows子系统】安装、启用、禁用以及同时支持docker-desktop和vmware方案

如果你要用docker桌面版&#xff0c;很可能会用到wsl&#xff0c;如果没配置好&#xff0c;很可能wsl镜像会占用C盘很多空间。 前提用管理员身份执行 wsl-windows子系统安装和启用 pushd "%~dp0" dir /b %SystemRoot%\servicing\Packages\*Hyper-V*.mum >hyper…

【前端知识】React 基础巩固(三十八)——log、thunk、applyMiddleware中间件的核心代码

React 基础巩固(三十八)——log、thunk、applyMiddleware中间件的核心代码 一、打印日志-中间件核心代码 利用Monkey Patching&#xff0c;修改原有的程序逻辑&#xff0c;在调用dispatch的过程中&#xff0c;通过dispatchAndLog实现日志打印功能 // 打印日志-中间件核心代码…

06. 管理Docker容器数据

目录 1、前言 2、Docker实现数据管理的方式 2.1、数据卷&#xff08;Data Volumes&#xff09; 2.2、数据卷容器&#xff08;Data Volume Containers&#xff09; 3、简单示例 3.1、数据卷示例 3.2、数据卷容器示例 1、前言 在生产环境中使用 Docker&#xff0c;一方面…

【FPGA + 串口】功能完备的串口测试模块,三种模式:自发自收、交叉收发、内源

【FPGA 串口】功能完备的串口测试模块&#xff0c;三种模式&#xff1a;自发自收、交叉收发、内源 VIO 控制单元 wire [1:0] mode;vio_uart UART_VIO (.clk(ad9361_l_clk), // input wire clk.probe_out0(mode) // output wire [1 : 0] probe_out0 );将 mod…

cyber_back

1.1 话题通信 模式&#xff1a; 以发布订阅的方式实现不同节点之间数据交互的通信模式。 如图1-1所示&#xff0c;Listener-Talker通信首先创建了两个Node&#xff0c;分别是Talker Node和 Listener Node。 每个Node实例化Writer类和Reader类对Channel进行消息的读写。 Writer…

211. 添加与搜索单词 - 数据结构设计---------------字典树

211. 添加与搜索单词 - 数据结构设计 原题链接&#xff1a;完成情况&#xff1a;解题思路&#xff1a;参考代码&#xff1a; 原题链接&#xff1a; 211. 添加与搜索单词 - 数据结构设计 https://leetcode.cn/problems/design-add-and-search-words-data-structure/descriptio…

Exadata磁盘损坏导致磁盘组无法mount恢复(oracle一体机磁盘组异常恢复)---惜分飞

Oracle Exadata客户,在换盘过程中,cell节点又一块磁盘损坏,导致datac1磁盘组&#xff08;该磁盘组是normal方式冗余)无法mount Thu Jul 20 22:01:21 2023 SQL> alter diskgroup datac1 mount force NOTE: cache registered group DATAC1 number1 incarn0x0728ad12 NOTE: ca…

【iOS】Frame与Bounds的区别详解

iOS的坐标系 iOS特有的坐标是&#xff0c;是在iOS坐标系的左上角为坐标原点&#xff0c;往右为X正方向&#xff0c;向下为Y正方向。 bounds和frame都是属于CGRect类型的结构体&#xff0c;系统的定义如下&#xff0c;包含一个CGPoint&#xff08;起点&#xff09;和一个CGSiz…

[游戏开发][Unity] 打包Xcode工程模拟器+真机调试

本文中会出现的名词有 苹果开发者账号、开发证书(.p12)、开发描述文(.mobileprovision)、发布证书(.p12)、发布描述文(.mobileprovision)、签名、授权电脑、授权iphone手机、 苹果开发者账号 账号分三类&#xff0c;个人&#xff0c;公司&#xff0c;企业&#xff0c;价格99…

windows使用多账户Git,多远程仓库版本管理

1 清除全局配置 git config --global --list // 看一下是否配置过user.name 和 user.email git config --global --unset user.name // 清除全局用户名 git config --global --unset user.email // 清除全局邮箱 2 本地仓库&#xff0c;每个远程对应的本地仓库目录下执行 $…

求三个球面交点的高效解法

文章目录 一、问题描述二、推导步骤代数法几何法 三、MATLAB代码 一、问题描述 如图&#xff0c;已知三个球面的球心坐标分别为 P 1 ( x 1 , y 1 , z 1 ) , P 2 ( x 2 , y 2 , z 2 ) , P 3 ( x 3 , y 3 , z 3 ) P_1(x_1,y_1,z_1),P_2(x_2,y_2,z_2),P_3(x_3,y_3,z_3) P1​(x1​,…