When thinking about Compose it's good to notice that Composables don't yield actual UI, but "emit" changes to the in-memory structure managed by the runtime (slot table) via the Composer.

That representation has to be interpreted later on to "materialize" UI from it 🧵 Image
An example of this is the Layout Composable, used to implement UI components. Layout uses ComposeNode to emit changes about how to create, update, index, and store the node on the table. That's why Composables return Unit 😲

cs.android.com/androidx/platf… ImageImage
Emitting these changes takes place via the compile time injected Composer, and it happens when the composable function is executed. That is during composition ⚙️
Layout belongs to compose-ui 🎨 That is code the developer writes. ComposeNode is part of the runtime, like the Composer and the slot table. See how node type is T in the runtime, so Compose can work with generic nodes to support other use cases. Image
Layout fixes generic type T to be ComposeUiNode, which is ultimately LayoutNode. In other words compose-ui decides what type of node to use Compose for 💡 Image
This separation between the in-memory representation of the graph and how it is interpreted allows to integrate with other libraries that use different types of nodes, making it possible to write libraries for desktop, web, or non UI related nodes.
The expectation is Composable functions are fast and restartable, so they simply schedule changes instead of building real UI. Composition traverses the 🌲 executing all Composable funcs to make them emit, ultimately filling up the table. It optimizes & prioritizes the process.
Recomposition happens multiple times and for different reasons, one of them being that the data being read by some elements on the tree has varied. That will make those functions to execute again (restart), and therefore emit again and update the table.
Once composition is done its time for materializing the changes from the table. The runtime delegates this to the "Applier", which is an interface implemented by compose-ui. It traverses the structure interpreting and materializing all nodes 🌲
“Materialize” is the verb used in Compose internals to refer to the action of interpreting the tree of changes to finally yield whatever output we are using Compose for. That is UI in the case of Android. The runtime is agnostic of the Applier's implementation.
The UiApplier implementation for Android delegates all actions to insert, move, remove or replace nodes to the node itself, a LayoutNode. LayoutNode is part of the UI library and provides the implementation details on how to materialize itself ✏️

This is where setContent becomes relevant. It adds an AndroidComposeView to the top level window decor view which draws all the Compose LayoutNodes to its own canvas. It sets itself as the owner of all the nodes, which is how it connects them with the View system 🔗
Here is where the relevant Android stuff like config, Context, LifecycleOwner, savedStateRegistryOwner, saveableStateRegistry & the actual owner view is linked and provided down the Composable tree via a CompositionLocalProvider, so you can access those things while coding 👩‍💻
The ultimate result of applying all the changes is that LayoutNodes are drawn to the AndroidComposeView Canvas whenever it receives the dispatchDraw() order, given it is an Android ViewGroup. ✅
Small disclaimer: If you read this 🧵 keep in mind all links are pointing to current indexed version in cs.android.com and that will likely vary over time since it’s all implementation details. That said, the overall spirit and concepts will remain.
I recommend reading this other thread as a continuation of this one. It clarifies the difference between the change list and the slot table. I was not able to dive that deep yet. Thanks @chuckjaz 👏

• • •

Missing some Tweet in this thread? You can try to force a refresh

Keep Current with Jorge Castillo 🍋

Jorge Castillo 🍋 Profile picture

Stay in touch and get notified when new unrolls are available from this author!

Read all threads

This Thread may be Removed Anytime!


Twitter may remove this content at anytime! Save it as PDF for later use!

Try unrolling a thread yourself!

how to unroll video
  1. Follow @ThreadReaderApp to mention us!

  2. From a Twitter thread mention us with a keyword "unroll"
@threadreaderapp unroll

Practice here first or read more on our help page!

Did Thread Reader help you today?

Support us! We are indie developers!

This site is made by just two indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3/month or $30/year) and get exclusive features!

Become Premium

Too expensive? Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal Become our Patreon

Thank you for your support!

Follow Us on Twitter!