Composition in Jetpack Compose
Composition in Jetpack Compose
Composition is the process Jetpack Compose uses to build and manage the UI tree by executing Composable functions. When a Composable function runs for the first time, Compose records it in an internal data structure and produces nodes that represent the UI hierarchy. This recorded structure is the Composition, and it serves as the single source of truth for what is currently displayed on screen. Understanding how a Composition is created, how it connects to the Android view system, and how it manages its lifecycle is a foundational topic in Compose development. By the end of this lesson, you will be able to:
- Explain what a Composition represents and how it relates to the UI tree.
- Describe how
ComponentActivity.setContentcreates a Composition throughComposeView. - Explain how
ComposeViewintegrates Compose into existing Android view hierarchies. - Identify when a Composition enters and leaves the composition, and how recomposition updates it.
What a Composition Represents
A Composition is a tree structure built by the Compose runtime when it executes Composable functions. Each node in this tree corresponds to a Composable call, and the runtime tracks the state, parameters, and position of every node using an internal data structure called the slot table.
The slot table stores values produced during composition, such as remember results, state objects, and the identity of each Composable in the tree. When state changes, the runtime consults the slot table to determine which Composable functions need to re-execute. This selective re-execution is recomposition.
A Composition does not produce pixels directly. Instead, it produces a tree of layout nodes that the layout and drawing phases consume to render the final UI.
Creating a Composition with setContent
The most common entry point for creating a Composition in an Android app is ComponentActivity.setContent. This function bridges the Android Activity lifecycle with the Compose runtime:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyApp()
}
}
}
Internally, setContent checks whether a ComposeView already exists in the Activity's content view. If one exists, it updates the content. If not, it creates a new ComposeView, attaches it to the window, and sets the Composable content:
public fun ComponentActivity.setContent(
parent: CompositionContext? = null,
content: @Composable () -> Unit
) {
val existingComposeView = window.decorView
.findViewById<ViewGroup>(android.R.id.content)
.getChildAt(0) as? ComposeView
if (existingComposeView != null) with(existingComposeView) {
setParentCompositionContext(parent)
setContent(content)
} else ComposeView(this).apply {
setParentCompositionContext(parent)
setContent(content)
setOwners()
setContentView(this, DefaultActivityContentLayoutParams)
}
}
This interview continues for subscribers
Subscribe to Dove Letter for full access to exclusive interviews about Android and Kotlin development.
Become a Sponsor