MutableState — kuzatiladigan holat va Compose-da yangilanish mexanizmi

Muallif: IT Sectr Nashr etilgan: 2026-06-28 O'qish vaqti: 7 daq

MutableState — Jetpack Compose-dagi o'zgaruvchan kuzatiladigan qiymat uchun konteynerni ifodalovchi interfeys. U Compose reaktiv tizimining asosini tashkil qiladi: MutableState qiymati setter orqali har safar o'zgarganda, Compose Runtime barcha o'qiyotgan komponentlarni xabardor qiladi va rekombinatsiyani ishga tushiradi. Google Android Developers, 2026 ma'lumotlariga ko'ra, MutableState-ni tushunish deklarativ UI-da holat bilan to'g'ri ishlash uchun majburiydir.

Asosiy fikrlar

  • MutableState — compose.runtime interfeysi, bitta value xossasi (getter + setter)
  • State — faqat o'qish uchun asosiy interfeys, MutableState yozish imkoniyatini qo'shadi
  • Rekombinatsiya faol snapshot siklida value setteri chaqirilganda ishga tushadi
  • SnapshotMutationPolicy o'zgarish rekombinatsiya uchun muhim deb hisoblangan vaqtni aniqlaydi
  • MutableIntState va analoglari — MutableState-ning optimallashtirilgan primitiv versiyalari

Jetpack Compose-da MutableState nima

MutableState — androidx.compose.runtime paketidagi interfeys bo'lib, bitta xossani e'lon qiladi: override var value: T. Getter joriy qiymatni qaytaradi, setter yangisini yozadi va Compose Runtime-ni o'zgarish haqida xabardor qiladi. Interfeys State<T> dan meros oladi, unda value faqat o'qish uchun mavjud. Bunday ikki darajali arxitektura kirishni ajratish imkonini beradi: faqat qiymatni o'qishi kerak bo'lgan komponent State<T> oladi, egalik qiluvchi komponent esa — MutableState<T>.

MutableState-ning standart tatbiqi ichki sinf SnapshotMutableStateImpl bo'lib, o'zgarishlarni kuzatish uchun snapshot mexanizmidan foydalanadi. Qiymat setteri chaqirilganda, joriy snapshot yozuvni qayd qiladi va barcha ro'yxatdan o'tgan ObservedScope-larni (kuzatish sohalari) yaroqsiz deb belgilaydi. Bu sohalar (odatda Composable funksiyalari) keyingi kadrda qayta tarkiblanadi. Butun jarayon Lock-free snapshot arxitekturasi tufayli sinxron va bloklanmasdan sodir bo'ladi.

State vs MutableState: State — komponentlarning umumiy API-lari uchun ishlatiladigan faqat o'qish uchun interfeys. Composable funksiyasining parametrini State<Int> deb e'lon qilganingizda, komponent o'qiy olishiga, lekin holatni o'zgartira olmasligiga kafolat berasiz. MutableState egalik qiluvchi komponent ichida ishlatiladi. Bunday ajratish — Compose-ning asosiy amaliyotlaridan biri bo'lib, ruxsatsiz o'zgarishlarning oldini oladi.

State, MutableState va hosila interfeyslarning iyerarxiyasi

Compose-dagi holat interfeyslari iyerarxiyasi bir necha darajaga ega. Tepasida — faqat o'qish uchun value bilan State<T>. Pastda — o'qish va yozish uchun value bilan MutableState<T>. Keyin ixtisoslashgan primitiv versiyalar keladi: MutableIntState, MutableFloatState, MutableLongState, MutableBooleanState va boshqalar, primitivlarning avtomatik qadoqlanishidan (boxing) qochadi.

MutableDoubleState va MutableLongState — kamroq tarqalgan, ammo mavjud turlar. Kolleksiya interfeyslari: MutableListState — ro'yxat ichidagi o'zgarishlarni kuzatish uchun, MutableStateMap — xaritalar uchun. Bu interfeyslarning har biri muayyan stsenariy uchun optimallashtirilgan va asosiy MutableState-ni kolleksiya bilan ishlash uchun qo'shimcha metodlar bilan kengaytiradi.

SnapshotStateList va SnapshotStateMap — snapshotlar bilan mos keladigan o'zgartiriladigan ro'yxat va xaritalarning tatbiqlari. Ular nafaqat qiymatni almashtirishni, balki ichki o'zgarishlarni ham kuzatish imkonini beradi: ro'yxatga element qo'shish, o'chirish, mavjud elementni o'zgartirish. Bunday tuzilmalar uchun mutableStateListOf() va mutableStateMapOf() tegishli kuzatiladigan kolleksiyalarni yaratadi.

InterfeysMaqsadYaratish metodi
State<T>Faqat o'qish uchun konteyner
MutableState<T>O'qish va yozish uchun konteynermutableStateOf()
MutableIntStateBoxingsiz primitiv IntmutableIntStateOf()
MutableFloatStateBoxingsiz primitiv FloatmutableFloatStateOf()
SnapshotStateListKuzatiladigan ro'yxatmutableStateListOf()
SnapshotStateMapKuzatiladigan xaritamutableStateMapOf()

SnapshotMutationPolicy: rekombinatsiya qachon ishga tushirilishi kerak

SnapshotMutationPolicy — MutableState o'zgarishi qachon muhim deb hisoblanishini aniqlaydigan interfeys. mutableStateOf policy-ni ikkinchi argument sifatida qabul qiladi. Standart tatbiqlar: structuralEquality() (equals), referentialEquality() (===), neverEqualPolicy() (har doim o'zgarishni muhim deb hisoblaydi). O'z mantiqingiz uchun o'z policy-ni tatbiq qilishingiz mumkin.

structuralEquality() — standart xatti-harakat. Compose yangi qiymatni eski bilan equals() orqali solishtiradi. Agar natija true bo'lsa — rekombinatsiya ISHGA TUSHMAYDI. Bu primitivlar va data klasslari uchun qulay, bunda bir xil maydonlarga ega ikkita namuna teng deb hisoblanadi. Muammo: agar data klass List ni o'z ichiga olsa, equals() chuqur solishtirishni amalga oshiradi, bu katta ro'yxatlar uchun qimmat bo'lishi mumkin.

referentialEquality() — referanslarni === orqali solishtiradi. Rekombinatsiya faqat boshqa obyekt tayinlanganda ishga tushadi, hatto mazmun bir xil bo'lsa ham. Bu o'zgarmas data klasslari uchun optimal, bunda har bir yangi namuna o'zgarishni kafolatlaydi. neverEqualPolicy() — har doim o'zgarishni muhim deb hisoblaydi, solishtirishni amalga oshirmasdan. Setter kamdan-kam chaqirilganda va equals-ga vaqt sarflash kerak bo'lmaganda foydali.

kotlin
    // Amaliyotda siyosatlarni taqqoslash
data class User(val name: String, val age: Int)

@Composable
fun UserProfile() {
    // structuralEquality: rekombinatsiya FAQAT ma'lumot o'zgarganda
    var user1 by remember {
        mutableStateOf(User("Alice", 30))
    }

    // referentialEquality: rekombinatsiya HAR bir tayinlashda
    var user2 by remember {
        mutableStateOf(User("Bob", 25),
            SnapshotMutationPolicy.referentialEquality())
    }

    // user1: copy() bir xil maydonlar bilan rekombinatsiyani ishga TUSHIRMAYDI
    // user2: hatto user2.copy() == user2 rekombinatsiyani ishga tushiradi (yangi ref)
}

Primitiv State: MutableIntState, MutableFloatState, MutableLongState

Primitiv MutableIntState va analoglari — primitivlarni avtomatik qadoqlash (boxing) holda saqlaydigan ixtisoslashgan interfeyslar. Oddiy MutableState<Int> Int ni Integer sifatida saqlaydi, har yozishda to'plamda obyekt yaratadi. MutableIntState int (primitiv) ni saqlaydi, qadoqlash yukini butunlay yo'q qiladi. Bu yuqori chastotali yangilanishlarda ayniqsa muhim — hisoblagichlar, scroll pozitsiyalari, animatsiya qiymatlari.

mutableIntStateOf(), mutableFloatStateOf(), mutableLongStateOf() — primitiv MutableState yaratuvchi funksiyalar. Interfeyslar MutableIntState, MutableFloatState, MutableLongState deb nomlanadi. Ular mos ravishda MutableState<Int>, MutableState<Float> va MutableState<Long> ni kengaytiradi, primitivga tezkor kirish uchun intValue xossasini qo'shadi. Ularning ichki tatbiqida lock-free o'qish/yozish uchun AtomicInteger ishlatiladi.

Qo'llanilishi: hisoblagichlar (Int), scroll pozitsiyalari (Float offset), vaqt belgilari (Long). Kundalik stsenariylarning aksariyatida ishlash farqi sezilmaydi, lekin minglab elementlarga ega LazyList va o'tish animatsiyalarida primitiv State sezilarli o'sish beradi. Google odatdagi stsenariylar uchun universal mutableStateOf o'rniga primitiv State-dan foydalanishni tavsiya qiladi.

kotlin
@Composable
fun ScrollCounter() {
    // Yomon: har bir yangilanishda qadoqlash
    var badCount by remember { mutableStateOf(0) }

    // Yaxshi: qadoqlash yo'q, primitiv saqlash
    var goodCount by remember { mutableIntStateOf(0) }

    // Foydalanish bir xil
    Button(onClick = { goodCount++ }) {
        Text("Count: $goodCount")
    }
}

MutableState bilan ishlashning amaliy misollari

TodoList komponentini ko'rib chiqaylik, bunda MutableState ikki shaklda ishlatiladi: kiritish holati uchun alohida o'zgaruvchilar va dinamik topshiriq ro'yxati uchun SnapshotStateList. Ikkalasi ham kodning qisqaligi uchun delegatsiyadan foydalanadi.

kotlin
data class TodoItem(val id: Int, val text: String, val isDone: Boolean = false)

@Composable
fun TodoScreen() {
    var inputText by remember { mutableStateOf("") }
    val items = remember { mutableStateListOf() }

    Column(modifier = Modifier.padding(16.dp)) {
        Row {
            TextField(
                value = inputText,
                onValueChange = { inputText = it }
            )
            Button(onClick = {
                if (inputText.isNotBlank()) {
                    items.add(TodoItem(items.size, inputText))
                    inputText = ""
                }
            }) { Text("Qo'shish") }
        }

        LazyColumn {
            items(items) { item ->
                Row(modifier = Modifier.fillMaxWidth().clickable {
                    val idx = items.indexOf(item)
                    items[idx] = item.copy(isDone = !item.isDone)
                }) {
                    Checkbox(checked = item.isDone, onCheckedChange = null)
                    Text(item.text)
                }
            }
        }
    }
}

mutableStateListOf SnapshotStateList yaratadi — alohida elementlarning o'zgarishlarini kuzatadigan o'zgartiriladigan ro'yxat. items.add() va items[n] = newValue chaqirilganda, Compose mutatsiyani ko'radi va faqat o'zgargan LazyColumn elementlarini qayta tarkiblaydi. inputText — oddiy MutableState<String>. Ikkala MutableState turining (yakka va kolleksiya) kombinatsiyasi — formalar va ro'yxatli ekranlar uchun odatiy naqsh.

Tez-tez so'raladigan savollar

MutableState-dan remembersiz foydalanish mumkinmi?

MutableState remembersiz har bir rekombinatsiyada qayta yaratiladi. Har bir yangi mutableStateOf chaqiruvi yangi obyekt yaratadi, eski qiymat yo'qoladi. Har doim rekombinatsiyalar orasida State-ni saqlash uchun remember-dan foydalaning, agar State Composable-dan tashqarida (masalan, ViewModel-da) yaratilmagan bo'lsa.

MutableState-ni oddiy o'zgaruvchiga qanday aylantirish mumkin?

.value ni snapshot-dan tashqarida snapshot { } orqali bir marta o'qing. Ammo bu reaktivlikni o'chiradi — o'zgarishlar endi rekombinatsiyani chaqirmaydi. Obunasiz bir martalik o'qish uchun snapshot ichida currentValue() dan foydalaning.

Qaysi biri tezroq: mutableStateOf yoki mutableIntStateOf?

mutableIntStateOf tezroq, chunki int ni Integer ga qadoqlashni talab qilmaydi. Sekundiga minglab yangilanishlarda (animatsiya, scroll) farq ajratish vaqtining 30-50% gacha yetishi mumkin. Kamdan-kam yangilanishlarda (kliklar, matn kiritish) farq ahamiyatsiz.

MutableState-ni Composable funksiyasining argumenti sifatida ishlatish mumkinmi?

Ishlatish mumkin, lekin tavsiya etilmaydi. MutableState o'rniga State (faqat o'qish) + onValueChange lambdasini uzating. Bu State Hoisting naqshini amalga oshiradi va komponentni qayta ishlatiladigan qiladi. MutableState qabul qiladigan komponentlar bir yo'nalishli ma'lumot oqimini buzadi.

MutableState-ning maxsus tatbiqini qanday yaratish mumkin?

MutableState interfeysini tatbiq qiling va getter va setter bilan override var value ni ta'minlang. Setterda validatsiya yoki loglash qo'shishingiz mumkin. Compose Runtime bilan orqaga moslik uchun tatbiqingizni snapshotFlow bilan o'rang yoki snapshotIncrement dan foydalaning.

Xulosa

  • MutableState — Compose-da o'zgaruvchan kuzatiladigan holat uchun asosiy interfeys
  • State — o'zgartirish huquqisiz ma'lumot uzatish uchun faqat o'qish versiyasi
  • SnapshotMutationPolicy o'zgarish vaqtida rekombinatsiyani ishga tushirish shartlarini boshqaradi
  • Primitiv State (MutableIntState va b.) avtomatik qadoqlash yukini yo'q qiladi
  • SnapshotStateList va SnapshotStateMap kolleksiyalarning ichki o'zgarishlarini kuzatadi
  • Rekombinatsiya value setterining har bir chaqiruvida avtomatik ishga tushadi
  • Tavsiya: holatga egalik qilish uchun MutableState, pastga uzatish uchun State dan foydalaning

Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz

IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.

Loyihani muhokama qilish

Shuningdek o'qing