min
09/07/2025, 5:59 PMthis.setContent {/* ... */} where this: ComponentActivity creates or otherwise obtains a ComposeView which usually uses the window Recomposer as the CompositionContext of the toplevel Composition of the view hierarchy. I also see that the .composition: Composition of the ComposeView has a private .composer: ComposerImpl field. (Note ComposerImpl: Composer)
private val composer: ComposerImpl =
ComposerImpl(
applier = applier,
parentContext = parent,
slotTable = slotTable,
abandonSet = abandonSet,
changes = changes,
lateChanges = lateChanges,
composition = this
).also {
parent.registerComposer(it)
}
As far as I can tell, the .parent: CompositionContext is typically the window Recomposer as that’s the default, but the implementation of registerComposer by Recomposer does nothing; It’s actually a no-op. So the activity has a window, which has
• A CompositionContext (a Recomposer)
• A ComposeView view hierarchy with a Composition that has a ComposerImpl: Composer
But the Recomposer does nothing when the ComposerImpl is passed to it via the .registerComposer(it). So how is it made aware of the composer, and how is everything put together?Chrimaeon
09/07/2025, 6:09 PMmin
09/07/2025, 6:11 PMRecomposer about the ComposerImpl?Chrimaeon
09/07/2025, 6:15 PMmin
09/08/2025, 5:38 AMmin
09/08/2025, 6:23 AMComponentActivity installed snapshot observers 🤔 But speaking of, the pointers Albert Chang provided let me eventually find out that the setContent method creates/obtains and mounts a ComposeView, which has a .composition: Composition field and a .resolveParentCompositionContext(): CompositionContext method to return the parent of the composition it hosts, which defaults to the window Recomposer. The ComposeView also gets/has a child AbstractComposeView which creates and returns the composition to store in `.composition: Composition`: In androidx.compose.ui.platform.doSetContent, a WrappedComposition is either obtained if already present or created by wrapping a CompositionImpl. The .setContent(content) call on the wrapped composition in turn calls the setContent method on the wrapped composition (which in this case is a CompositionImpl) which in turn calls the composeInitial method of its context (which in this case is the window Recomposer). The composeInitial method of Recomposer calls composing on the receiver, which contains…
val snapshot = Snapshot.takeMutableSnapshot(
readObserverOf(composition), writeObserverOf(composition, modifiedValues)
)
try {
return snapshot.enter(block)
} finally {
applyAndCheck(snapshot)
}
…this code to take and observe a snapshot. So why did you tell me to have a look at Applier? It didn’t turn out to be relevant, unless I’m missing something. If I am, please let me know in the other thread since I’m asking a new different question in this threadChrimaeon
09/08/2025, 7:02 AMmin
09/08/2025, 7:24 AMshikasd
09/08/2025, 12:00 PMcomposeInitial works