Jetpack compose——深入了解recomposition的工作原理

news2024/11/15 23:28:41

一、compose怎么 实现响应式编程的

Jetpack Compose 是 Android 的现代 UI 工具包,它使用 Kotlin 语言的声明式 UI 模式来简化 UI 开发。在这种模式中,你只需描述 UI 应该如何根据应用的状态进行显示,而 Compose 会在状态发生变化时自动更新 UI。这就是 Compose 实现响应式编程的方式。

在 Compose 中,你可以使用 mutableStateOfremember 函数来创建可观察的状态。当这些状态发生变化时,所有依赖这些状态的 Composable 函数都会重新调用,从而更新 UI。

以下是一个简单的例子:

@Composable
fun Counter() {
    var count by remember { mutableStateOf(0) }

    Button(onClick = { count++ }) {
        Text("You clicked $count times")
    }
}

在这个例子中:

  • mutableStateOf(0) 用于创建一个可变的状态,其初始值为 0。remember 函数用于在重新组合时记住这个状态。
  • Button Composable 用于创建一个按钮。当按钮被点击时,count 的值会增加。
  • Text Composable 用于显示一段文本,这段文本显示了按钮被点击的次数。当 count 的值发生变化时,Text Composable 会自动更新。

这就是 Compose 如何实现响应式编程的基本原理。你只需描述 UI 应该如何根据状态进行显示,Compose 会在状态发生变化时自动更新 UI。

二、compose底层逻辑

Jetpack Compose 的底层逻辑是基于 Kotlin 的协程和函数式编程的概念。这是一种声明式 UI 框架,它的工作方式与传统的命令式 UI 框架有所不同。

在命令式 UI 框架中,开发者需要手动管理 UI 的状态和生命周期,当应用的状态发生变化时,需要手动更新 UI。这种方式可能会导致代码复杂且难以维护。

而在声明式 UI 框架(如 Jetpack Compose)中,UI 是应用状态的函数。开发者只需要描述 UI 在给定状态下应该如何显示,框架会在状态发生变化时自动重新调用这些函数,从而更新 UI。

Jetpack Compose 使用了一种名为 "recomposition" 的技术来实现这一点。当可观察的状态发生变化时,Compose 会找到依赖这些状态的所有 Composable 函数,并重新调用它们。这就是为什么当你更改 mutableStateOf 的值时,所有使用这个状态的 Composable 函数都会自动更新。

Compose 的底层还使用了一种名为 "diffing" 的技术来优化性能。当 Composable 函数被重新调用时,Compose 会比较新旧 UI 树,并只更新实际发生变化的部分。这意味着即使你的应用有大量的 UI,Compose 也能保持高效的性能。

三、recomposition技术的实现

etpack Compose 的 recomposition 技术是通过 Kotlin 的协程和 Compose 编译器插件实现的。这个插件会转换你的 Composable 函数,使它们能够在状态发生变化时重新调用。

当你在 Composable 函数中使用 mutableStateOfremember 创建状态时,Compose 编译器插件会自动跟踪这些状态。当状态发生变化时,Compose 会找到所有依赖这些状态的 Composable 函数,并重新调用它们。这就是 recomposition 的基本工作原理。

这个过程是自动进行的,你不需要手动触发 recomposition。你只需要使用 mutableStateOfremember 创建状态,并在 Composable 函数中使用这些状态,Compose 就会自动处理 recomposition。

这种自动的 recomposition 机制使得在 Compose 中创建响应式 UI 变得非常简单。你只需要描述 UI 在给定状态下应该如何显示,Compose 会在状态发生变化时自动更新 UI。

需要注意的是,recomposition 只会影响依赖发生变化的状态的 Composable 函数。如果一个 Composable 函数不依赖任何状态,或者它依赖的状态没有发生变化,那么这个函数就不会被重新调用。这是 Compose 的一种优化机制,它可以确保只有真正需要更新的部分才会被重新调用。

四、recomposition 的基本工作原理

  1. 状态跟踪:当你在 Composable 函数中使用 mutableStateOfremember 创建状态时,Compose 编译器插件会自动跟踪这些状态。这意味着 Compose 知道哪些 Composable 函数依赖哪些状态。

  2. 状态变化:当状态发生变化时(例如,你调用了 count++ 来增加一个计数器的值),Compose 会知道这个状态已经改变。

  3. 重新调用 Composable 函数:Compose 会找到所有依赖已改变状态的 Composable 函数,并重新调用它们。这就是所谓的 "recomposition"。重新调用 Composable 函数会导致 UI 更新,因为 Composable 函数描述了 UI 应该如何根据当前状态进行渲染。

  4. 优化:Compose 使用一种称为 "diffing" 的技术来优化 recomposition。当 Composable 函数被重新调用时,Compose 会比较新旧 UI,并只更新实际发生变化的部分。这意味着即使你的应用有大量的 UI,Compose 也能保持高效的性能。

 

流程如下:

  1. Composable函数使用状态。
  2. 当状态发生变化时,Compose编译器插件会被触发。
  3. 编译器插件触发recomposition。
  4. 在recomposition过程中,所有依赖已改变状态的Composable函数会被重新调用。

这个过程是自动进行的,你不需要手动触发 recomposition。你只需要使用 mutableStateOfremember 创建状态,并在 Composable 函数中使用这些状态,Compose 就会自动处理 recomposition。这使得在 Compose 中创建响应式 UI 变得非常简单。你只需要描述 UI 在给定状态下应该如何显示,Compose 会在状态发生变化时自动更新 UI。

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

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

相关文章

【Linux】oh-my-zsh终端配置

😏★,:.☆( ̄▽ ̄)/$:.★ 😏 这篇文章主要介绍oh-my-zsh终端配置。 学其所用,用其所学。——梁启超 欢迎来到我的博客,一起学习,共同进步。 喜欢的朋友可以关注一下,下次更新不迷路&am…

Spring Boot发送QQ邮件

Spring Boot发送QQ邮件 1. 创建Spring Boot项目2. 引入发邮件的starter3. 必要配置4. 编写邮件内容5. 测试其他&#xff1a; Spring Boot简单引入一个包就能轻松发邮件&#xff0c;仅需5分钟就能实现 1. 创建Spring Boot项目 略 2. 引入发邮件的starter <dependency>&l…

学习在外部Python脚本中运行Houdini的Python接口(hou模块)

0. 目标 学习在外部Python脚本&#xff08;而非Houdini编辑器内部&#xff09;使用 hou 。 主要参考Houdini官方文档 Command-Line Scripting 中的【Accessing hou from a Regular Python Shell】部分。我将要点记录在下&#xff1a; 1. 将Houdini的dll加入搜索路径 为了能…

FPGA实验五:信号发生器设计

目录 一、实验目的 二、设计要求 三、实验代码 1.代码原理分析 2.代码设计思路 3.IP核的设计与配置 四、实验结果及分析 1、引脚锁定 2、仿真波形及分析 &#xff08;1&#xff09;关于波形一些指标的介绍 &#xff08;2&#xff09;对波形转换功能的验证 &#xf…

【LeetCode】225. 用队列实现栈

225. 用队列实现栈&#xff08;简单&#xff09; 思路 要使用一个队列来实现栈的功能。 具体来说&#xff0c;实现了以下几个方法&#xff1a; push(int x)&#xff1a;将元素 x 入栈&#xff0c;即将元素 x 插入到队列的末尾。pop()&#xff1a;弹出栈顶元素&#xff0c;即将队…

空天遥感守护自然资源底线,擦亮生态底色

上期介绍了航天宏图采用“空天地”一体化监测监管手段&#xff0c;打造基于“SAR卫星耕地变化遥感智能解译”、 基于“遥感大模型的耕地分类技术”等智慧耕地保护解决方案&#xff0c;本篇文章主要讲述“遥感如何助力自然保护地监测与保护”和“如何助力山水林田湖草沙生态修复…

Spanner: Google的全球分布级数据库----论文摘要

Spanner中一个新奇的time api揭示了时钟的不确定性。该api及其实现对于支持外部一致性&#xff08;外部观察一致性&#xff09;以及一系列强力的特性至关重要&#xff0c;这些特性包括&#xff1a;对过去版本数据的无阻塞读&#xff08;对于历史数据的读不加锁&#xff0c;且不…

密码学入门——DES与AES

文章目录 参考书目一、编码与异或1.1 编码1.2 异或 二、DES与三重DES三、AES 参考书目 图解密码技术&#xff0c;第三版 一、编码与异或 1.1 编码 计算机的操作对象并不是文字&#xff0c;而是由0和1排列而成的比特序列。无论是文字、图像、声音、视频还是程序&#xff0c;…

短视频矩阵管理系统源码开发:视频批量剪辑,分发功能开发示例

短视频矩阵管理系统开发&#xff0c;首先对服务器要求&#xff1a; 源码所需服务器配置 1、规格&#xff1a;最低8核16G 2、硬盘&#xff1a;系统盘40-100G&#xff0c;数据盘不低于100G 3、带宽&#xff1a;10M 4、系统&#xff1a;CentOS7(务必选择7.*) 部署过程中&…

设计模式之结构型模式---代理模式

目录 1.概述2.代理模式类图3.应用场景3.1 功能增强3.2 控制访问 4.实现4.1 静态代理的实现4.1.1 实现静态代理模式的步骤4.1.2 静态代理的缺点 4.2 动态代理的实现4.2.1 Java JDK 动态代理的实现MethodInvocationHandlerProxy 4.2.2 JDK动态代理的使用方法4.2.3 JDK动态代理的实…

本内容由【想发APP】创始人编写:uniAPP申请百度广告后,开发者必须要空包签名验证应用的所有权,实现的详细内容如下

Android获取签名 注意先安装好jdk和jre&#xff0c;然后配置好环境变量 说明 空包签名需要本地配置jdk环境 Windows 安装JDK及环境变量的配置 命令行方式 命令格式&#xff1a; jarsigner -verbose -keystore [签名文件路径] -signedjar [签名后apk的文件路径] [未签名apk的文…

对顶堆学习笔记

对顶堆学习笔记 文章目录 **对顶堆学习笔记**介绍例题洛谷 P1168 中位数code 介绍 对顶堆是由一个大顶堆和一个小顶堆组合而成的数据结构&#xff0c;与传统堆维护最大数不同&#xff0c;对顶堆用于动态维护第k大的数。 对于对顶堆&#xff0c;我们可以用两个优先队列来表示两…

IllegalArgumentException: OnNoRibbonDefaultCondition异常与Maven Helper插件解决jar包冲突

在搭建Spring Cloud项目时&#xff0c;引入了不同版本的jar&#xff0c;导致项目启动时报错: main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.Bea…

Python 制作英文学习词典(简易版)

前言 今日分享 Python 制作英文学习词典&#xff0c;大家都可以尝试。 题目 制作英文学习词典。编写程序制作英文学习词典&#xff0c;词典有3个基本功能&#xff1a;添加、查询和退出。程序读取源文件路径下的txt格式词典文件&#xff0c;若没有就创建一个。词典文件存储方…

arcgis js 4.x加载自定义坐标系的arcgis server发布的wms服务

一、问题描述 一般城市本身用的都是自己定义的城市&#xff08;本地&#xff09;坐标系&#xff0c;没有对应公开的EPSG代码&#xff0c;如下图如果直接加载自定义坐标系的wms服务&#xff0c;直接会报错。 var customProjLayer new WMSLayer({url: "http://10.1.8.37:6…

封装一个带el-form的,带el-table的,带分页的,带搜索查询的dialog组件,很使用的二次封装组件。

#封装dialog小案例 提示&#xff1a;这是我工作中封装的代码&#xff0c;很使用&#xff0c;需要的可以拿去&#xff0c; 在我们的代码中往往会出现点击按钮出现弹窗进行操作&#xff0c;那么我们就需要对dialog进行一个二次封装。 下边是大概的一个样式。 ##对组件进行二次…

C语言中一维数组及二维数组的运用

1、int arr[] {12,3,4,5,6}; int * p arr; int * q &arr[1]; 其中arr是数组名&#xff0c;代表了整个数组的首元素地址&#xff0c;这个是一个常量&#xff0c;放在常量存储区&#xff0c;所以在给int*p赋值的时候可以不用带&&#xff0c;而下面的arr[1]则代表数…

unidbg或者java层解密方法IDEA中打包成jar包供python调用方法

一、导出jar包方法 &#xff08;1&#xff09;配置jar包参数 &#xff08;2&#xff09;创建生成jar包 成功生成&#xff01; 二、Python代码调用 import jpypejvmPath jpype.getDefaultJVMPath() d unidbg-android.jar # 对应jar地址 jpype.startJVM(jvmPath, "-ea&q…

cloudflared tunnel后台启动

前期视频链接 先前台启动&#xff0c;本文参考 cloudflared tunnel --url localhost:88 run ruoyu 或者 cloudflared tunnel --url localhost:88 --no-chunked-encoding run ruoyu找到你的uuid.json 文件 创建你的config.yaml 或config.yml 内容如下 uuid 配置自己的 url: …

创建员工表并按要求完成数据

mysql> create table employee( id int primary key, name varchar(50), gender enum(男,女) default 男, salary int ); Query OK, 0 rows affected (0.01 sec)mysql> mysql> desc employee; ------------------------------------------------------ | Field | T…