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 — 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.
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.
| Interfeys | Maqsad | Yaratish metodi |
|---|---|---|
| State<T> | Faqat o'qish uchun konteyner | — |
| MutableState<T> | O'qish va yozish uchun konteyner | mutableStateOf() |
| MutableIntState | Boxingsiz primitiv Int | mutableIntStateOf() |
| MutableFloatState | Boxingsiz primitiv Float | mutableFloatStateOf() |
| SnapshotStateList | Kuzatiladigan ro'yxat | mutableStateListOf() |
| SnapshotStateMap | Kuzatiladigan xarita | mutableStateMapOf() |
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.
// 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 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.
@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")
}
}
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.
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 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.
.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.
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.
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 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
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.