Composition: esensya, pagbuo ng UI tree sa Compose

May-akda: IT Sectr Nai-publish: 2026-06-27 Oras ng pagbabasa: 7 min

Composition — ay ang sentral na proseso sa Jetpack Compose, kung saan mula sa mga deskriptibong Composable function ay binuo ang isang buhay na UI tree na ipinapakita sa screen. Hindi tulad ng View system sa Android, kung saan ang layout ay nilo-load mula sa XML at ginagawang hindi nababagong mga bagay, ang Composition ay gumagana bilang isang dynamic na sistema: ang mga function ay isinasagawa, lumikha ng mga slot sa memorya, bumubuo ng hierarchy ng mga node at iniuugnay ito sa estado. Ayon sa Google Android Developers, 2026, ang pag-unawa sa Composition ay kritikal para sa pag-optimize ng performance ng Compose application.

Mga pangunahing punto

  • Composition — pagpapatupad ng Composable function para bumuo ng UI tree
  • Mga Slot — mga memory cell na nag-iimbak ng mga parameter at estado ng bawat function
  • Posisyon sa Compose (Positional Memorization) ay nagbubuklod ng estado sa lugar sa code
  • Unang daan Composition ay lumilikha ng paunang UI tree sa pagsisimula ng screen
  • CompositionLocal ay nagpapadala ng data sa pamamagitan ng tree nang walang tahasang mga parameter

Ano ang Composition sa Jetpack Compose

Composition — ay ang proseso ng pagpapatupad ng Composable function, na nagreresulta sa panloob na representasyon ng user interface sa anyo ng isang tree ng mga node. Ang bawat node ng tree na ito ay tumutugma sa alinman sa isang built-in na component (Text, Button, Image) o isang tawag sa isang custom na Composable function. Ang Composition ay hindi direktang lumilikha ng Android View objects — ito ay bumubuo ng abstract na paglalarawan na pagkatapos ay pinoproseso ng Layout at Drawing phases.

Ang pangunahing katangian ng Composition ay ang restartability nito. Ang bawat Composable function sa komposisyon ay maaaring i-restart anumang oras kung ang mga input parameter nito o ang mga state object na binasa nito ay nagbago. Hindi ni-restart ng system ang buong tree — tanging ang mga function na talagang umaasa sa binagong data.

Sa teknikal, ang Composition ay pinamamahalaan sa pamamagitan ng Composer — isang panloob na engine na ini-embed ng Kotlin compiler sa bawat Composable function. Ang Composer ay nagsusulat sa mga slot (mga grupo ng posisyon) ng impormasyon tungkol sa kung aling mga function ang tinawag, sa anong mga parameter, at sa anong pagkakasunud-sunod. Sa mga susunod na tawag, inihahambing ng Composer ang bagong data sa naka-save at nagpapasya tungkol sa pag-restart.

Paano binuo ang UI tree sa proseso ng Composition

Ang proseso ng pagbuo ng UI tree ay nagsisimula sa pagtawag sa paraang setContent sa loob ng Activity o Fragment. Ang paraang ito ay lumilikha ng paunang Composition at naglulunsad ng pagpapatupad ng root Composable function. Pagkatapos, ang bawat nested Composable function ay nagdaragdag ng mga node nito sa tree, na bumubuo ng hierarchy: Row ay naglalaman ng Text at Button, Column ay naglalaman ng Image at Card, at iba pa.

Ang bawat node ng tree ay nakakakuha ng isang natatanging key ng posisyon, batay sa posisyon nito sa source code. Ang key na ito ay ginagamit para sa pagkilala ng node sa mga paulit-ulit na pagpapatupad. Ang key ng posisyon ay ang dahilan kung bakit ang pagkakasunud-sunod ng pagtawag ng Composable function ay hindi dapat umasa sa mga kondisyon: kung sa isang pagpapatupad ay tinawag ang A -> B, at sa susunod ay B -> A, hindi magagawa ng Compose na itugma ang luma at bagong mga node.

kotlin
@Composable
fun AppScreen() {
    Column {                     // Column node (posisyon 1)
        HeaderSection()            // HeaderSection node (posisyon 2)
        ContentSection()           // ContentSection node (posisyon 3)
        FooterSection()            // FooterSection node (posisyon 4)
    }
}

@Composable
fun HeaderSection() {
    Row {                       // Row node (posisyon 2.1)
        Text("Pamagat")         // Text node (posisyon 2.2)
        Icon(...)                // Icon node (posisyon 2.3)
    }
}

Sa halimbawang ito, ang bawat tawag ay nakakakuha ng posisyon batay sa pagkakasunud-sunod sa code. Column (posisyon 1) ay naglalaman ng tatlong child node (posisyon 2, 3, 4). Ang HeaderSection ay nagdaragdag ng dalawa pang child node (2.1, 2.2, 2.3). Kung sa susunod na recomposition ang ContentSection ay tinawag bago ang HeaderSection, hindi magagawa ng Composer na itugma nang tama ang mga node — kaya ang patakaran: ang pagkakasunud-sunod ng pagtawag ng Composable function ay dapat na matatag.

Pamamahala ng estado sa Composition

Ang estado sa Composition ay pinamamahalaan sa pamamagitan ng mga bagay na uri ng State<T>. Kapag ang isang Composable function ay nagbabasa ng halaga mula sa State sa pamamagitan ng delegadong property (by), nagrerehistro ito ng dependency sa State na iyon. Kapag nagbago ang halaga, ang lahat ng function na nagbasa ng State na ito ay minarkahan para sa pag-restart sa susunod na yugto ng komposisyon.

Ang mekanismo ng pagrerehistro ng mga dependency ay tinatawag na snapshot system. Sa bawat oras na nagbago ang State, ang snapshot ay nagtatala ng lahat ng pagbabago at nag-abiso sa Composer kung aling mga function ang nakadepende sa State na ito. Mahalagang maunawaan: ang pagbabasa ng State sa non-Composable na code (hal. sa onClick lambda) ay hindi nagrerehistro ng dependency — tanging ang pagbabasa sa loob ng Composable function o sa mga lambda na isinagawa sa konteksto ng komposisyon.

Ang snapshot system ay gumagana nang transaksyonal: maraming pagbabago ng State sa loob ng isang kaganapan ay pinagsama sa isang transaksyon, na pumipigil sa maraming recomposition. Ito ay lalong mahalaga sa pagproseso ng mga kilos: sa isang paggalaw, maraming State object ang nagbabago, ngunit ang Compose ay nagsasagawa lamang ng isang recomposition.

kotlin
@Composable
fun StateExample() {
    var text by remember { mutableStateOf("Hello") }
    var isVisible by remember { mutableStateOf(true) }

    Column {
        Text(text)  // nagrerehistro ng dependency sa text

        if (isVisible) {  // nagrerehistro ng dependency sa isVisible
            TextField(value = text, onValueChange = { text = it })
        }

        Button(onClick = { isVisible = !isVisible }) {
            Text(if (isVisible) "Itago" else "Ipakita")
        }
    }
}

Ang pagbabago ng text ay humahantong sa recomposition lamang ng Column, Text at TextField. Ang Button at ang kondisyong isVisible ay nananatiling hindi nagbabago. Ang ganitong pagkakahiwalay ng recomposition ay isang pangunahing bentahe ng Compose kumpara sa mga system na nagre-redraw ng buong screen. Bawat Composable function ay sumusubaybay lamang sa mga State object na direktang binabasa nito.

Composition vs Recomposition: mga pangunahing pagkakaiba

Composition (komposisyon) at Recomposition (rekomposisyon) — ay dalawang magkaibang mode ng pagpapatupad ng Composable function. Ang Composition ay nangyayari nang isang beses sa paggawa ng screen: isinasagawa ng system ang lahat ng Composable function na may paunang halaga at binuo ang paunang UI tree. Ang Recomposition ay nangyayari nang maraming beses sa pagbabago ng data: ni-restart ng system ang mga function lamang na nakadepende sa binagong estado.

Ang mode na Composition ay nag-activate ng lahat ng node ng tree, naglalaan ng mga slot para sa bawat function, nagrerehistro ng lahat ng descendant. Ang Recomposition ay gumagana nang pili: inihahambing ng Compose ang mga bago at lumang halaga ng parameter ng bawat function, at kung hindi nagbago — ang function ay hindi isinasagawa (skipping).

Ang Composition at Recomposition ay nagkakaiba sa gastos. Ang unang Composition ay mas mahal, dahil nangangailangan ito ng kumpletong pagbuo ng tree at paglalaan ng mga slot. Ang Recomposition ay mas mura, lalo na kung ang karamihan sa mga function ay stable — ang kanilang mga parameter ay inihahambing sa pamamagitan ng equals, at nilalampasan ng Compose ang kanilang tawag. Para sa maximum na pagganap, dapat sikaping ang kaunting mga function hangga't maaari ay maapektuhan ng recomposition.

KatangianCompositionRecomposition
Kailan nangyayariIsang beses, sa unang pagpapakitaMaraming beses, sa pagbabago ng data
SaklawBuong treeTanging mga binagong function
Paghahambing ng parameterHindi isinasagawaIsinasagawa para sa skipping
Paglikha ng slotOo, lahat ng slot ay nilikhaTanging para sa mga bagong node

CompositionLocal: pagpapadala ng data sa pamamagitan ng tree

CompositionLocal — isang mekanismo ng implicit na pagpapadala ng data sa pamamagitan ng composition tree. Nalulutas nito ang problema kapag ang isang parameter ay kailangang ipadala sa pamamagitan ng dose-dosenang nested Composable function na hindi ito direktang ginagamit. Sa halip ng isang tahasang chain ng mga parameter, ang data ay itinakda sa itaas na antas at binabasa sa anumang nested function sa pamamagitan ng CompositionLocal.current.

Ang temang MaterialTheme — ang pinakakilalang halimbawa ng CompositionLocal. Lahat ng component ng Compose ay nagbabasa ng mga kulay, typography at mga hugis sa pamamagitan ng MaterialTheme.colorScheme, MaterialTheme.typography, MaterialTheme.shapes, nang hindi tumatanggap ng mga ito sa pamamagitan ng mga parameter. Ang developer ay maaaring lumikha ng sariling CompositionLocal para sa data tulad ng kasalukuyang user, mga setting ng lokalisasyon, o configuration ng screen.

Mahalagang limitasyon: ang CompositionLocal ay hindi dapat gamitin para sa madalas na nagbabagong data (posisyon ng scroll, text sa input field). Ang component na nagbabasa ng CompositionLocal ay ni-restart sa bawat pagbabago ng halaga, kaya para sa dynamic na data mas mainam na gumamit ng tahasang mga parameter o State. Ang CompositionLocal ay pinakamainam para sa configuration data na bihira o hindi nagbabago.

kotlin
val LocalUser = compositionLocalOf<User?> { null }

@Composable
fun AppRoot(user: User, content: @Composable () -> Unit) {
    CompositionLocalProvider(LocalUser.provides(user)) {
        content()
    }
}

@Composable
fun UserAvatar() {
    val user = LocalUser.current  // pagbabasa nang walang tahasang parameter
    AsyncImage(model = user?.avatarUrl, contentDescription = "Avatar")
}

Ang CompositionLocalProvider ay lumilikha ng isang sakop ng visibility, kung saan ang LocalUser.current ay nagbabalik ng itinakdang halaga. Ang UserAvatar ay nagbabasa ng user nang walang tahasang pagpapadala ng parameter sa pamamagitan ng mga intermediate function. Ito ay lalong mahalaga sa malalalim na hierarchy kung saan ang data ay kailangan lamang sa ilang leaf node.

Mga madalas itanong

Ano ang mangyayari kung ang State ay binago habang Composition?

Ang pagbabago ng State habang Composition ay nag-iiskedyul ng bagong recomposition na isasagawa pagkatapos matapos ang kasalukuyan. Walang loop na nangyayari: ginagarantiyahan ng Compose na ang bawat recomposition ay isinasagawa sa isang hiwalay na transaksyon ng snapshot system.

Gaano katagal ang Composition ng isang kumplikadong screen?

Sa mga modernong device, ang Composition ng isang screen na may 50–100 Composable function ay tumatagal ng 1–5 ms. Inirerekomenda ng Google na manatili sa loob ng 16 ms bawat frame sa 60fps. Kung lumampas ang Composition sa limitasyong ito, gamitin ang LazyColumn o hatiin ang screen sa mas maliliit na function.

Maaari bang manu-manong simulan ang Composition?

Ang direktang manu-manong pagsisimula ng Composition ay hindi posible — ito ay awtomatikong pinamamahalaan ng Composer. Gayunpaman, maaaring pilitin na mag-iskedyul ng recomposition sa pamamagitan ng pagbabago ng State o pagtawag sa invalidate() sa root composite, kung may access sa CompositionContext.

Paano naiiba ang Composition sa View hierarchy sa klasikong Android?

Ang View hierarchy — ay isang hindi nababagong tree ng Java object na nilikha nang isang beses. Composition — isang virtual tree na itinayong muli sa bawat pagbabago ng data. Iniimbak ng View ang estado nito sa mga instance variable, Composition — sa mga slot na nakatali sa posisyon ng tawag ng function.

Paano pinangangasiwaan ng Composition ang pagtanggal ng node?

Kung ang isang Composable function ay tumigil sa pagtawag (hal. ang kondisyong if ay naging false), tinatanggal ng Composition ang node nito at tinatawagan ang paglilinis ng DisposableEffect. Sa muling paglitaw (if ay naging true muli) isang bagong node ang nilikha — ang luma ay hindi na-restore.

Buod

  • Composition — proseso ng pagpapatupad ng Composable function para bumuo ng UI tree na nakatali sa estado
  • Composer ay namamahala ng mga slot, nagtatala ng mga tawag ng function at naghahambing ng mga parameter sa recomposition
  • Snapshot system ay nagrerehistro ng mga dependency ng function sa State at pinagsasama ang mga pagbabago sa mga transaksyon
  • Composition ay isinasagawa nang isang beses sa pagsisimula, Recomposition — sa pagbabago ng data
  • CompositionLocal ay nagpapadala ng configuration data sa pamamagitan ng tree nang walang tahasang chain ng parameter
  • Posisyon ng tawag ng function ay nagsisilbing natatanging identifier nito sa composition tree
  • Rekomendasyon: gawing maliit ang Composable function na may hindi nababagong mga parameter para sa epektibong skipping

Gagawa kami ng mobile application na turnkey

Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.

Pag-usapan ang proyekto

Basahin din