Jetpack Compose 深入探索系列一:Composable 函数

Composable 函数的含义

如果我们只专注于简单的语法,任何标准的Kotlin函数都可以成为一个可组合函数,只需将其注解为@Composable:

在这里插入图片描述

通过这样做,我们实际上是在告诉编译器,该函数打算将一些数据转换为一个Node节点,以便注册到可组合树中。也就是说,如果我们将可组合函数看成是 @Composable (Input) -> Unit,输入是数据,但输出却不是大多数人认为的函数返回的值,而是一个将元素插入树中的注册动作。我们可以认为这是一种函数执行带来的副作用。

这里所谓的 “注册动作” 在 Compose 中通常称为 “emitting”(发射)。emit 动作是在可组合函数被执行时进行的,这发生在组合过程中。

在这里插入图片描述
执行Composable函数的唯一目的是构建或更新树的内存表示状态。这将使它始终与其所代表的树结构保持同步更新状态,因为可组合函数会在其读取的数据每次发生变化时重新执行。为了保持和树的同步更新状态,它们可以发出插入新节点的操作(如上所述),但同样也可以删除、替换或移动节点。可组合函数还可以从树中读取或向树中写入状态。

Composable 函数的属性

将函数注解为Composable还有其他相关含义。@Composable注解有效地更改了它所应用的函数或表达式的类型,并且与任何其他类型一样,它对其施加了一些约束或属性。这些属性与Jetpack Compose非常的紧密相关,因为它们可以解锁Compose库的相关功能。

Compose runtime 期望Composable函数遵守上述属性,因此它可以假定某些行为,并利用不同的运行时优化,如并行组合、基于优先级的任意组合顺序、智能重组或位置记忆等等。

一般来说,只有当运行时对需要运行的代码有一定的确定性时,才可能进行运行时优化,因此它可以从中假设特定的条件和行为。这解锁了执行的时机,或者换句话说,利用上述确定性来 “消费” 这段代码,以便遵循不同的执行策略或评估技术。

这些确定性的一个例子是代码中不同元素之间的关系。他们是否相互依赖? 我们可以在不影响程序的情况下,并行或以不同的顺序运行它们吗?我们能把每个原子逻辑片段解释为一个完全孤立的单元吗?

调用上下文

可组合函数的大多数属性是由Compose编译器启用的。因为它是一个Kotlin编译器插件,所以它在正常的编译器阶段运行,并且可以访问到所有的Kotlin编译器可以访问的信息。这允许它拦截和转换来自我们所有可组合函数的 IR (intermediate representation,中间产物表示),以便添加一些额外的信息。

其中,Compose编译器 为每一个 Composable 函数都会新增的一个东西就是在参数列表的末尾附加了一个 Composer 参数。这个参数是隐式的,也就是说开发者在编写代码时并不会感知到这一点。它的实例是在运行时被注入的,并被转发给所有的子Composable调用,因此它可以从树的所有级别中被访问到。

在这里插入图片描述

假设我们有如下代码:

在这里插入图片描述

那么Compose编译器会将其翻译成下面这样:

在这里插入图片描述

我们可以看到,Composer被转发到了body内的所有Composable调用。在此基础上,Compose编译器对可组合函数施加了严格的规则:它们只能从其他可组合函数调用。因为这实际是需要调用上下文,它确保树只由可组合函数组成,以便Composer可以被向下转发。

Composer是我们作为开发者编写的可组合代码与Compose runtime之间的连接桥梁。可组合函数将使用它来发射对树的更改操作,从而通知 Compose runtime 树的形状,以便构建或更新其内存表示状态。

幂等

可组合函数相对于它们生成的节点树是幂等的。也就是说:使用相同的输入参数多次重新执行一个Composable函数应该会得到相同的树。Jetpack Compose运行时依赖于这个假设来进行重新组合之类的事情。

在Jetpack Compose中,重组是在可组合函数的输入发生变化时重新执行的动作,这样它们就可以发射更新后的信息并更新树。 Compose runtime必须能够在任意时间,根据各种原因重新组合可组合函数。

重组过程将遍历整个树,检查哪些节点需要重新组合(重复执行)。只有具有输入变化的节点将重新组

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

川峰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值