鸿蒙系列-如何使用好 ArkUI 的 @Reusable?

如何使用好 ArkUI 的 @Reusable?

OpenHarmony 组件复用机制

在ArkUI中,UI显示的内容均为组件,由框架直接提供的称为 系统组件,由开发者定义的称为 自定义组件

在进行 UI 界面开发时,通常不是简单的将系统组件进行组合使用,而是需要考虑代码可复用性、业务逻辑与UI分离,后续版本演进等因素。因此,将UI和部分业务逻辑封装成自定义组件是不可或缺的能力。

本文主要对组件复用做一些基本介绍,然后对 @Reusable做分析,进而帮助开发者理解设置前后的效果,以及我们会尝试寻找何时使用这个属性最佳,进而给开发者提出参考方案。

为什么要组件复用?

使用组件复用往往是解决资源短缺的问题,通过节约内存节省资源,简称开源节流。

开源节流是我国理财的基本原则之一。开源指开拓财政收入来源,节流指尽可能减少不必要的支出,或少花钱多办事。

荀子《富国》
荀子在《富国》篇中说“故田野县鄙者,财之本也;垣窌仓廪者,财之末也;百姓时和,事业得叙者,货币之源也;等赋府库者,货之流也。故明君必养其和、节其流、开其源而时斟酌焉。”其意系指农业是创造财富的根本大业,聚财只是其结果,货币只是流通的手段,财政收入只能从流通中取得,故用扩大流通的方式来增加收入,对增加财富并无好处。

同理,鸿蒙系统的内存是非常宝贵的,它不仅需要提供给底层系统维持系统正常运行,还要分配给网络、通知、后台任务、传感器、中断等一系列工作。那么我们在应用开发时就要想办法节约内存,为系统工作分忧。

@Reusable组件复用装饰器

在 ArkUI中,使用 @Component装饰器修饰组件,组件允许开发者组合使用系统组件、及其属性和方法,并通过状态变量的改变,来驱动UI的刷新。 @Reusable是修饰组件的属性,赋予组件重用的特性。
在这里插入图片描述

什么是@Reusable?

@Reusable 是一个装饰器,它可以标识自定义组件具备可复用的能力,也可以被添加到任意的自定义组件上。并且也可以在跨平台提供响应的能力。整体来说,它是 ArkUI的一部分。

它的定义如下:

/**
 * Defining Reusable ClassDecorator.
 *
 * @syscap SystemCapability.ArkUI.ArkUI.Full
 * @crossplatform
 * @since 10
 */
declare const Reusable: ClassDecorator;

可以看出,Reusable 实际上是一个 ClassDecorator , 那么它的内部结构是如何的呢?

从上图可以分析并查看 component构造函数:

    constructor(parent, localStorage, elmtId = -1) {
        super();
        ...
        this.recycleManager = undefined;
        ...
}

component的构造函数中我们发现,每一个 component持有一个 recycleManagerrecycleManager参与管理 Reusable 组件,那么 recycleManager是如何管理复用组建的呢?

接下来我们再看它的后端实现逻辑:

视图层的关系如下:

视图层是通过js实现的,

  1. xxx
  2. xxx

…todo

我们在视图树的结构中发现一个环,众所周知,环会产生内存泄漏,所以在页面退出时,需要将 RecycleManager中持有的view全部手动释放,以此来破环。

当组件被重用时,就会触发 aboutToReuse 方法:

aboutToReuse?(params: { [key: string]: unknown }): void;

在这个函数中就可以重载数据。

连接层的关系如下:

连接层是桥接 js 和 c++的中间层。

我们在 js_ace_page.h文件中发现以下代码,可以验证持有关系。

namespace OHOS::Ace::Framework {

...
private:
#ifndef NG_BUILD
    void SwapBackgroundDecoration(const RefPtr<PageTransitionComponent>& transition);
#endif
    ...
    RefPtr<Component> component_;
...
}

节点层的关系如下:

节点层是通过c++实现的。

  1. xxx
  2. xxx

…todo

那么我们接下来看下组件复用发生和不发生时的区别:

组件复用发生时:

在复用组件在view显示后,组织结构如下:

在c++
构造树中,当@Reusable修饰的组建复用后,JSView强持有c++的view,page的实例被RecycleManager 管理持有。

此时如果page被回收,由于 c++的view 被jsview强持有,就无法得到释放。所以需要在c++的析构中,对RecycleManager中所有的 复用组件释放,完成手动释放。

组件复用不发生时:

在复用组件从view移除后,组织结构发生如下变化:

在c++
构造树中,当@Reusable修饰的组建删除后,JSView不再强持有c++的view,此时c++的view被RecycleManager 管理持有,等待下一次被重用。

此时如果page被回收,由于 c++的view 并没有被jsview强持有,就可以得到释放。

。。todo

实战:@Reusable 可以解决的问题:

现在我们知道了 @Reusable 的基本功能,那么它在实际开发中可以解决什么问题呢?根据我的思考🤔️和整理,主要可以解决以下三类问题。

问题一:解决组件嵌套过深:

子组件通过@Prop接收父组件传递的数据,如果嵌套的层数过多,会导致深拷贝占用的空间过大以及GarbageCollection(垃圾回收),引起性能问题。通过 @Reusable可解决嵌套的层数过多的问题。

那么 @Reusable是如何解决这个问题的?请看下文:

我们在开发时往往会遇到多层组件嵌套的场景,通俗说就是view中套子view,子view中又套孙子view,以此类推。
这样就会产生一个嵌套过深的问题参考,见下图:

具体代码如下:

@Entry
@Component
struct FatherView {
  @State vote: ClassE = new ClassE()

  build() {
    Column() {
      Button('change')
        .onClick(() => {
          this.vote.name = "I'm Father"
        })
      Child({ voteOne: this.vote })
    }
  }
}

@Component
struct SonView {
  @Prop voteOne: ClassE

  build() {
    Column() {
      Button('change')
        .onClick(() => {
          this.vote.name = "I'am Son"
        })
      Child({ voteTwo: this.vote })
    }
  }
}


@Component
struct SonView {
  @Prop voteTwo: ClassD

  build() {
    Column() {
      Button('change')
        .onClick(() => {
          this.vote.name = "I'am grandson"
        })
      Child({ voteThree: this.vote })
    }
  }
}

...

在不断增加层次后,问题产生了:

  1. 由于层次过深,代码难以阅读,并且传递关系过于复杂,传递依赖链过长,不满足第三范式。
    第三范式:表中每一列的属性都不可再分,且非主属性完全依赖于主属性,且每个非主属性都不传递函数依赖于主属性。 https://en.wikipedia.org/wiki/Third_normal_form

  2. 可能触发GarbageCollection(垃圾回收机制),产生问题。

具体什么条件会触发,暂无资料,还需要相关子系统提供源码分析🧐。

那么在使用 @Reusable优化后的效果如下:

具体代码如下:

@Entry
@Component
struct FatherView {
  @State vote: ClassE = new ClassE()

  build() {
    Column() {
      Button('change')
        .onClick(() => {
          this.vote.name = "I'm Father"
        })
      Child({ voteOne: this.vote })
    }
  }
}

@@Reusable
@Component
struct SonView {
  @Prop voteOne: ClassE

  build() {
    Column() {
      Button('change')
        .onClick(() => {
          this.vote.name = "I'am Son"
        })
      Child({ voteTwo: this.vote })
    }
  }
}

@@Reusable
@Component
struct SonView {
  @Prop voteTwo: ClassD

  build() {
    Column() {
      Button('change')
        .onClick(() => {
          this.vote.name = "I'am grandson"
        })
      Child({ voteThree: this.vote })
    }
  }
}

...

在使用 @Reusable优化后,问题解决了:

  1. 消除了传递依赖,代码层次结构更清晰了,对于组件间互相交互也更好处理,在深拷贝的传递链上已满足第三范式。

  2. 深度只有2层,100%避免了由于深度增加触发GarbageCollection(垃圾回收机制)的条件,避免产生问题。

问题二:减少创建控件时间:

。。todo

问题三:使代码更优雅:

。。todo

总结:

。。todo

个人观点:

。。todo

相关扩展:

。。todo

– 缓冲池机制:

传统的 LRU:

什么是预读失败?

什么是缓冲池污染?

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python实现语音识别

1. 首先安装依赖库 pip install playsound # 该库用于播放音频文件 pip install speech_recognition # 该库用于语音识别 pip install PocketSphinx # 语音识别模块中只有sphinx支持离线的&#xff0c;使用该模块需单独安装 pip install pyttsx3 # 该库用于将文本转换为语音播…

自动化运维工具-----Ansible入门详解

目录 一.Ansible简介 什么是Ansible&#xff1f; Ansible的特点 Ansible的架构 二.Ansible任务执行解析 ansible任务执行模式 ansible执行流程 ansible命令执行过程 三.Ansible配置解析 ansible的安装方式 ansible的程序结构&#xff08;yum安装为例&#xff09; ansibl…

设计模式-5--适配器模式(Adapter Pattern)

一、什么是适配器模式&#xff08;Adapter Pattern&#xff09; 适配器模式&#xff08;Adapter Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许将一个类的接口转换成客户端所期望的另一个接口。适配器模式主要用于解决不兼容接口之间的问题&#xff0c;使得原本…

Netty-ChannelPipeline

EventLoop可以说是 Netty 的调度中心&#xff0c;负责监听多种事件类型&#xff1a;I/O 事件、信号事件、定时事件等&#xff0c;然而实际的业务处理逻辑则是由 ChannelPipeline 中所定义的 ChannelHandler 完成的&#xff0c;ChannelPipeline 和 ChannelHandler应用开发的过程…

[dasctf]misc05

盲水印 png里藏jpg&#xff0c;bwm.py可以提取含flag的图片

git学习笔记 | 版本管理 - 分支管理

文章目录 git学习笔记Git是什么仓库常见的命令commit 备注规范在文件下设置git忽略文件 .gitignore 版本管理git log | git reflog 查看提交日志/历史版本版本穿梭 git resetgit reset HEAD <file> git checkout -- fileName 丢弃工作区的修改git revertGit恢复之前版本的…

论文阅读_扩散模型_SDXL

英文名称: SDXL: Improving Latent Diffusion Models for High-Resolution Image Synthesis 中文名称: SDXL&#xff1a;改进潜在扩散模型的高分辨率图像合成 论文地址: http://arxiv.org/abs/2307.01952 代码: https://github.com/Stability-AI/generative-models 时间: 2023-…

3D视觉测量:形位公差 面对面平行度(附源码)

文章目录 0. 测试效果1. 基本内容1.1 面对面平行度概述2. 代码实现文章目录:3D视觉测量目录微信:dhlddxB站: Non-Stop_0. 测试效果 1. 基本内容 “平行度” 是用来描述两个或多个对象或方向之间的平行关系的度量。在几何和工程学中,平行度通常用于衡量物体、表面、线条或方向…

mac帧 arp

1.分片 2.MSS max segment size 3.跨网络的本质 就是经历很多的子网或者局域网 4.将数据从A主机跨网络送到B主机的能力 IP和mac IP解决的是路径选择的问题 5.数据链路层 用于两个设备&#xff08;同一种数据链路节点&#xff09;之间进行传递 6.以太网ether 7.局域网通…

圆圈加数字的css

方式一 .circle { width: 50px; height: 50px; border-radius: 50%; background-color: #f00; color: #fff; text-align: center; line-height: 50px; } .circle::before { content: attr(data-number); display: block; } <div class"circle" data-number"…

ChatGPT总结(持续更新)

目录 体验渠道 weTab CSDN-AI助手 其他插件 ChatGPT简介 ChatGPT主要用途 ChatGPT发展历程 GPT-4架构的特点和优势 ChatGPT的工作原理 神经网络和自然语言处理技术 Transformer模型 模型训练优化技巧 ChatGPT对程序员的帮助 与ChatGPT交互和提问技巧 ChatGPT未来…

50ETF期权开户平台(0门槛期权开户指南)

50ETF期权开户平台比较好的有&#xff1a;期权馆&#xff0c;期权科普馆&#xff0c;小熊期权&#xff0c;期权酱&#xff0c;财顺财经&#xff0c;财顺期权等&#xff0c;都是国内前十的期权分仓平台&#xff0c;下文为大家结算50ETF期权开户平台&#xff08;0门槛期权开户指南…

SoC 总线结构学习记录之系统存储总线(System Memory Bus)与私有设备总线

蜂鸟 E203 SOC总线结构&#xff1a;  蜂鸟 E203 内核 BIU 的系统存储接口 ICB 连接系统存储总线&#xff0c;通过其访问 SoC 中的若干存储组件&#xff0c;譬如 ROM&#xff0c;Flash 的只读区间等。  蜂鸟 E203 内核 BIU 的私有设备接口 ICB 连接私有设备总线&#xff0c…

mac电脑屏幕录制Berrycast Mac屏幕录制软件

Berrycast是一款为Mac设计的优秀屏幕录制软件&#xff0c;它让屏幕录制变得简单而高效。以下是Berrycast的一些主要特点&#xff1a; 简单的用户界面&#xff1a;Berrycast拥有直观和简洁的用户界面&#xff0c;使得用户可以轻松上手。高质量的视频输出&#xff1a;Berrycast能…

Sharding-JDBC介绍及分库分表实践

1.1 ShardingSphere简介 最早是当当网内部使用的一款分库分表框架&#xff0c;名字叫Sharding-JDBC&#xff0c;定位为轻量级 Java 框架&#xff0c;在 Java 的 JDBC 层提供的额外服务。 它使用客户端直连数据库&#xff0c;以 jar 包形式提供服务&#xff0c;无需额外部署和依…

机器人中的数值优化(六)—— 线搜索最速下降法

本系列文章主要是我在学习《数值优化》过程中的一些笔记和相关思考&#xff0c;主要的学习资料是深蓝学院的课程《机器人中的数值优化》和高立编著的《数值最优化方法》等&#xff0c;本系列文章篇数较多&#xff0c;不定期更新&#xff0c;上半部分介绍无约束优化&#xff0c;…

C语言每日一练--Day(16)

本专栏为c语言练习专栏&#xff0c;适合刚刚学完c语言的初学者。本专栏每天会不定时更新&#xff0c;通过每天练习&#xff0c;进一步对c语言的重难点知识进行更深入的学习。 今日练习题关键字&#xff1a;寻找奇数 峰值 二分查找 &#x1f493;博主csdn个人主页&#xff1a;小…

《数字图像处理-OpenCV/Python》连载(4)图像的读取与保存

《数字图像处理-OpenCV/Python》连载&#xff08;4&#xff09;图像的读取与保存 本书京东优惠购书链接&#xff1a;https://item.jd.com/14098452.html 本书CSDN独家连载专栏&#xff1a;https://blog.csdn.net/youcans/category_12418787.html 第1章 图像的基本操作 为了方…

【MyBatisⅡ】动态 SQL

目录 &#x1f392;1 if 标签 &#x1fad6;2 trim 标签 &#x1f460;3 where 标签 &#x1f9ba;4 set 标签 &#x1f3a8;5 foreach 标签 动态 sql 是Mybatis的强⼤特性之⼀&#xff0c;能够完成不同条件下不同的 sql 拼接。 在 xml 里面写判断条件。 动态SQL 在数据库里…

vr智慧党建主题展厅赋予企业数字化内涵

现如今&#xff0c;VR全景技术的发展让我们动动手指就能在线上参观博物馆、纪念馆&#xff0c;不仅不用受时间和空间的限制&#xff0c;还能拥有身临其境般的体验&#xff0c;使得我们足不出户就能随时随地学习、传承红色文化。 很多党建展厅都是比较传统的&#xff0c;没有运用…