前言

compose已经熟悉了几周了,跟着google sample进行理解时,对可组合函数参数列表如何声明,事件向上,数据向下传递理解还是有偏差。重新理解了下compose编程思想

1.早期基于View 微件数:

更新界面:多个需要同时更新View,会遗漏。复杂的View微件更新会更新前面已经移除过微件的状态

2.声明性范式:

tips:mvvm 为数据驱动界面ui更新。 界面(Fragment,Activity)订阅ViewModel中的LiveData,数据发生变化时通知界面进行刷新。而lifecycle系列避免发生订阅内存泄露而引入的辅助管理类。

compose:一个声明性界面框架,【完全重新生成一个屏幕】

声明性范式转变

View微件数:在许多面向对象的命令式界面工具包中,您可以通过实例化微件树来初始化界面。您通常通过Inflate XML 布局文件来实现此目的。每个微件都维护自己的内部状态,并且提供 getter 和 setter 方法,允许应用逻辑与微件进行交互。

Compose 的声明性方法中:微件相对无状态,并且不提供 setter 或 getter 函数,微件不会以对象形式提供,您可以通过调用带有不同参数的同一可组合函数来更新界面

界面描述:自上而下

应用逻辑为顶级可组合函数提供数据,该函数(顶级可组合函数)通过调用其他可组合函数来使用这些数据描述界面,将适当的数据传递给这些可组合函数,并沿层次结构向下传递数据

事件响应:自下而上

例如:触发onclick事件,这些事件应通知应用逻辑,应用逻辑随后可以改变应用的状态。当状态发生变化时,系统会使用新数据再次调用可组合函数。这会导致重新绘制界面元素,此过程称为“重组”。

单选按钮点击,应用逻辑将单选按钮状态由check变为checked。状态变化导致compose函数 重组

可组合函数内不建议缓存临时变量,包含匿名函数,除非特别简单。建议将状态和数据提取到可组合函数外面使可组合函数幂等

重组

1.切勿依赖于执行可组合函数所产生的附带效应,因为可能会跳过函数的重组

附带效应:对应用的其余部分可见的任何更改

写入共享对象的属性
更新 ViewModel 中的可观察项
更新共享偏好设置

可组合函数可能会像每一帧一样频繁地重新执行,如果您需要执行成本高昂的操作(例如从共享偏好设置读取数据),请在[后台协程]中执行,并将值结果作为参数传递给可组合函数。

本文档讨论了您在 Compose 中编程时需要注意的事项:

可组合函数可以按任何顺序执行:

可组合函数均应该是幂等的,不应该依赖声明函数顺序,臆想程序执行顺序是序列化

可组合函数可以并行执行。

如果您看一下可组合函数的代码,可能会认为这些代码按其出现的顺序运行。但其实未必是这样。如果某个可组合函数包含对其他可组合函数的调用,这些函数可以按任何顺序运行。Compose 可以选择识别出某些界面元素的优先级高于其他界面元素,因而首先绘制这些元素。

例如,假设您有如下代码,用于在标签页布局中绘制三个屏幕:

@Composable
fun ButtonRow() {MyFancyNavigation {StartScreen()MiddleScreen()EndScreen()}
}

对 StartScreen、MiddleScreen 和 EndScreen 的调用可以按任何顺序进行。这意味着,举例来说,您不能让 StartScreen() 设置某个全局变量(附带效应)并让 MiddleScreen() 利用这项更改。相反,其中每个函数都需要保持独立。

可组合函数可以并行运行

Compose 可以通过并行运行可组合函数来优化重组。这样一来,Compose 就可以利用多个核心,并以较低的优先级运行可组合函数(不在屏幕上)。

这种优化意味着,可组合函数可能会在后台线程池中执行。如果某个可组合函数对 ViewModel 调用一个函数,则 Compose 可能会同时从多个线程调用该函数。

为了确保应用正常运行,所有可组合函数都不应有附带效应,而应通过始终在界面线程上执行的 onClick 等回调触发附带效应。

调用某个可组合函数时,调用可能发生在与调用方不同的线程上。这意味着,应避免使用修改可组合 lambda 中的变量的代码,既因为此类代码并非线程安全代码,又因为它是可组合 lambda 不允许的附带效应。

以下示例展示了一个可组合项,它显示一个列表及其项数:

@Composable
fun ListComposable(myList: List<String>) {Row(horizontalArrangement = Arrangement.SpaceBetween) {Column {for (item in myList) {Text("Item: $item")}}Text("Count: ${myList.size}")}
}

此代码没有附带效应,它会将输入列表转换为界面。此代码非常适合显示小列表。不过,如果函数写入局部变量,则这并非线程安全或正确的代码:

@Composable
@Deprecated("Example with bug")
fun ListWithBug(myList: List<String>) {var items = 0Row(horizontalArrangement = Arrangement.SpaceBetween) {Column {for (item in myList) {Text("Item: $item")items++ // Avoid! Side-effect of the column recomposing.}}Text("Count: $items")}
}

在本例中,每次重组时,都会修改 items。这可以是动画的每一帧,或是在列表更新时。但不管怎样,界面都会显示错误的项数。因此,Compose 不支持这样的写入操作;通过禁止此类写入操作,我们允许框架更改线程以执行可组合 lambda。

重组会跳过尽可能多的可组合函数和 lambda。

重组是乐观的操作,可能会被取消:

只要 Compose 认为某个可组合项的参数可能已更改,就会开始重组。重组是乐观的操作,也就是说,Compose 预计会在参数再次更改之前完成重组。如果某个参数在重组完成之前发生更改,Compose 可能会取消重组,并使用新参数重新开始。

取消重组后,Compose 会从重组中舍弃界面树。如有任何附带效应依赖于显示的界面,则即使取消了组成操作,也会应用该附带效应。这可能会导致应用状态不一致。

确保所有可组合函数和 lambda 都幂等且没有附带效应,以处理乐观的重组。

可组合函数可能会像动画的每一帧一样非常频繁地运行
最佳做法都是使可组合函数保持快速、幂等且没有附带效应。

compose编程思想 https://developer.android.com/jetpack/compose/mental-model

compose 编程思想相关推荐

  1. 深入浅出聊聊Java函数式编程思想

    引言 一直以来,Java都被认为是一种面向对象的编程语言,"万事万物皆对象"的思想已经深入人心.但随着Java8的发布,一切看起来似乎有些改变.Lambda表达式和Stream的引 ...

  2. 第1章 JVM语言家族概览 《Kotin 编程思想·实战》

    第1章 JVM语言家族概览 天地和而万物生,阴阳接而变化起.<荀子·礼记> 1.1 编程语言简述 1.1.1 编程语言是什么 所谓编程语言只是一个抽象的规范,而编译器是这个规范的实现,它是 ...

  3. 类的包访问权限:《Java编程思想》中一段话的困惑

    类的包访问权限:<Java编程思想>中一段话的困惑 在<java编程思想第三版>(陈昊鹏 饶若楠等译)的第五章隐藏具体实现中,5.4节的最后一段话是: "正如前面所提 ...

  4. 译者招募 | 《Java编程思想》作者Bruce Eckel新作On Java 8

    硅谷创业之父Paul Graham曾在<黑客与画家>中写道,"判断一种语言是否流行的条件是,一种免费的实现,一本相关书籍,以及语言所依附的计算机系统." 当然,Java ...

  5. 《Java编程思想》学习笔记(三)——初始化与清理

    一.初始化 初始化其实就是为变量分配内存空间,并确定其初始值的过程.想了解Java中初始化的各种情况,首先要了解Java中变量的类型.根据自己的理解,将Java中的变量类型分成以下几种,虽然可能不太准 ...

  6. 《Java编程思想》第四版读书笔记 第十四章 类型信息

    2019独角兽企业重金招聘Python工程师标准>>> 14.2 RTTI运行时类型识别. Class对象包含了与类有关的信息,Java使用Class对象来执行其RTTI.每个类都有 ...

  7. 几种常用编程语言的编程思想和方法 转

    搞软件的人,编程语言的掌握是基本功,如果单单是学习语法,最慢的一周之内也应该可以搞定(个人认为 语法层面c++是最复杂的).不幸的是,软件的本质是逻辑,解决方案的设计是要借助某种解决问题或编程的思想的 ...

  8. 1.1.3 以类为单位的编程思想

    我的克隆过程,是通过这个语句完成的SqlConnection conn = new SqlConnection(); ,你不会有意见吧? 二.执行查询命令并显示查询结果 打开数据库,总要做点事,我们来 ...

  9. java编程思想 入门_java编程思想学习(基础)

    第一章 java介绍 1.编程的本质: 机器空间:解空间 问题空间:实际需要解决的业务问题,将该问题抽象化,在解空间中对问题建模. 编程就是建立问题空间和机器空间中的关联 面向对象编程思想: 1.万物 ...

最新文章

  1. 使用 Java Native Interface 的最佳实践
  2. SAP PM入门系列33 - IP16 维修计划报表
  3. vue 加载时掉用mounted_Vue实例中生命周期created和mounted的区别详解
  4. linux重装系统后 70-persistent-net.rules 不能删除解决
  5. java 10-4 Scanner方法
  6. 如何转载-CSDN博客
  7. mysql utf8mb4 造成慢_mysql使用utf8mb4经验吐血总结
  8. 高考志愿怎么填?BOSS直聘发布了一份填报指南
  9. 风控模型中的变量替换
  10. 沙盘erp模拟人机对抗如何将公司经营6年
  11. 有什么软件可以把音频mp3格式转为文字?
  12. 笔记本ubuntu,deepin,linux系统共享WIFI
  13. 连续仨月霸占牛客榜首,京东T8呕心巨作:700页JVM虚拟机实战手册
  14. 学习金字塔:输出式主动学习
  15. 统计学习导论之R语言应用(四):分类算法R语言代码实战
  16. Kindle资源-史上最全60GB的Kindle技术电子书资源网盘打包下载
  17. Qt5工程文件详解及使用方法
  18. 8 种方案机智应对后端一次性返回 10万 条数据
  19. Win11系统白名单列表如何添加软件
  20. Android底部导航栏切换页面填坑

热门文章

  1. BSCI官网如何下载审核图片记录?
  2. android自定义水平长方形进度条,Android 自定义水平进度条的圆角进度
  3. keil仿真||示波器的使用
  4. fetch 服务器不响应,Fetch 常见的使用问题
  5. PostgreSQL 查看版本号
  6. 如何开启服务器2003远程,windows2003远程界面如何开启3389端口
  7. 浅谈iOS尺寸单位pt、ppi与px
  8. 网络地址转换(NAT)
  9. Android趣味课程:打地鼠游戏
  10. 【计算机组成原理】实验2:ALU(Verilog)中海大