这个android教程有以下代码片段:
@Composable
private fun MyApp() {
Surface(color = MaterialTheme.colors.background) {
Greeting("Android")
}
}
我的第一个想法是,通过调用包含子元素的lambda参数并将其作为返回值返回,从而获得它的问候子函数。但在本教程的后面,我们将得到以下示例:
@Composable
private fun Greeting(name: String) {
Surface(color = MaterialTheme.colors.primary) {
Column(modifier = Modifier.padding(24.dp)) {
Text(text = "Hello,")
Text(text = name)
}
}
}
无论如何,列都知道"Hello“文本和name文本,尽管调用lambda只会将名称文本作为返回值。
所以我的问题是:是什么机制让一个可组合的人意识到自己的孩子?
发布于 2021-12-31 06:30:33
类似于例如suspend
函数,@Composable
函数由编译器以非常特殊的方式处理。这是为了允许自动重新组合,并隐式地在组件之间传递上下文。
@Composable的文档指定:
可组合函数的一个有用的心智模型是,隐式“可组合上下文”被传递到可组合函数中,并在从另一个可组合函数中调用时隐式传递。此“上下文”可用于存储以前在树的同一逻辑点执行函数的信息。
通过编写一个简单的可组合函数并分析生成的字节码,我们可以看到它的作用。使用此源代码:
@Composable
fun Foo() {
Text("foo")
}
我们得到由数百条指令组成的字节码,其中一些得到的代码甚至被放置在一个单独的合成类中。我们将把重点放在最重要的部分:
public static final void Foo(androidx.compose.runtime.Composer, int);
正如我们所看到的,我们的无参数Foo()
函数实际上隐式地接收一个Composer
和一些整数。
3: invokeinterface #24, 2 // InterfaceMethod androidx/compose/runtime/Composer.startRestartGroup:(I)Landroidx/compose/runtime/Composer;
另一个Composer
对象是通过调用接收到的Composer
上的startRestartGroup()
获得的。
55: invokestatic #73 // Method androidx/compose/material/TextKt."Text-fLXpl1I":(Ljava/lang/String;Landroidx/compose/ui/Modifier;JJLandroidx/compose/ui/text/font/FontStyle;Landroidx/compose/ui/text/font/FontWeight;Landroidx/compose/ui/text/font/FontFamily;JLandroidx/compose/ui/text/style/TextDecoration;Landroidx/compose/ui/text/style/TextAlign;JIZILkotlin/jvm/functions/Function1;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/runtime/Composer;III)V
这是打给Text()
的电话。由于有大量的可选参数,所以很难读取,但是我们可以注意到它也接收到了一个Composer
对象。这个参数是合成的,我们在Text()
参数列表中找不到它--类似于我们的Foo()
函数。
Foo()
将startRestartGroup()
获得的作曲家传递给Text()
。
虽然我不知道Composer
的确切功能和含义,但我们可以清楚地看到,Compose框架隐式地传递可组合函数之间的上下文,从而可以将组件连接在一起。
https://stackoverflow.com/questions/70528010
复制相似问题