当前位置:   article > 正文

深入详解 Jetpack Compose | 实现原理

jetpack compose 持久话 sharedpre

本文是 Compose 系列的第二篇文章。在第一篇文章中,我已经阐述了 Compose 的优点、Compose 所解决的问题、一些设计决策背后的原因,以及这些内容是如何帮助开发者的。此外,我还讨论了 Compose 的思维模型、您应如何考虑使用 Compose 编写代码,以及如何创建您自己的 API。

在本文中,我将着眼于 Compose 背后的工作原理。但在开始之前,我想要强调的是,使用 Compose 并不一定需要您理解它是如何实现的。接下来的内容纯粹是为了满足您的求知欲而撰写的。

@Composable 注解意味着什么?

如果您已经了解过 Compose,您大概已经在一些代码示例中看到过 @Composable 注解。这里有件很重要的事情需要注意—— Compose 并不是一个注解处理器。Compose 在 Kotlin 编译器的类型检测与代码生成阶段依赖 Kotlin 编译器插件工作,所以无需注解处理器即可使用 Compose。

这一注解更接近于一个语言关键字。作为类比,可以参考 Kotlin 的 suspend 关键字:

  1. // 函数声明
  2. suspend fun MyFun() { … }
  3.  
  4. // lambda 声明
  5. val myLambda = suspend { … }
  6.  
  7. // 函数类型
  8. fun MyFun(myParam: suspend () -> Unit) { … }

Kotlin 的 suspend 关键字适用于处理函数类型: 您可以将函数、lambda 或者函数类型声明为 suspend。Compose 与其工作方式相同: 它可以改变函数类型。

  1. // 函数声明
  2. @Composable fun MyFun() { … }
  3.  
  4. // lambda 声明
  5. val myLambda = @Composable { … }
  6.  
  7. // 函数类型
  8. fun MyFun(myParam: @Composable () -> Unit) { … }

这里的重点是,当您使用 @Composable 注解一个函数类型时,会导致它类型的改变: 未被注解的相同函数类型与注解后的类型互不兼容。同样的,挂起 (suspend) 函数需要调用上下文作为参数,这意味着您只能在其他挂起函数中调用挂起函数:

  1. fun Example(a: () -> Unit, b: suspend () -> Unit) {
  2. a() // 允许
  3. b() // 不允许
  4. }
  5. suspend
  6. fun Example(a: () -> Unit, b: suspend () -> Unit) {
  7.    a() // 允许
  8. b() // 允许
  9. }

Composable 的工作方式与其相同。这是因为我们需要一个贯穿所有的上下文调用对象。

  1. fun Example(a: () -> Unit, b: @Composable () -> Unit) {
  2.    a() // 允许
  3. b() // 不允许
  4. }
  5. @Composable
  6. fun Example(a: () -> Unit, b: @Composable () -> Unit) {
  7. a() // 允许
  8. b() // 允许
  9. }

执行模式

所以,我们正在传递的调用上下文究竟是什么?还有,我们为什么需要传递它?

我们将其称之为 "Composer"。Composer 的实现包含了一个与 Gap Buffer (间隙缓冲区) 密切相关的数据结构,这一

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/917577
推荐阅读
相关标签
  

闽ICP备14008679号