LaunchedEffect: bu nima, koroutinlar va Jetpack Compose-da boshqarish

Muallif: IT Sectr Nashr etilgan: 2026-06-30 O'qish vaqti: 9 daq

LaunchedEffect — bu Jetpack Compose-dagi komponentning hayotiy sikliga bog'langan koroutin ichida asinxron operatsiyalarni bajarish uchun mo'ljallangan composable-funktsiyadir. U composable-elementi kompozitsiyaga kirganda kod blokini ishga tushiradi va chiqishda avtomatik ravishda bekor qiladi. Bu LaunchedEffect-ni ma'lumotlarni yuklash, Flow-ga obuna bo'lish va taymerlar bilan ishlash uchun asosiy vositaga aylantiradi. Android Documentation (2025) ma'lumotlariga ko'ra, LaunchedEffect asinxron ma'lumotlar bilan ishlaydigan Jetpack Compose ilovalarining 85 foizida qo'llaniladi.

Asosiy ma'lumotlar

  • LaunchedEffect — kompozitsiya kontekstida koroutinlarni ishga tushirish uchun side-effect API.
  • Kalitlar — kalitlar o'zgarganda koroutin bekor qilinadi va yangi qiymatlar bilan qayta ishga tushiriladi.
  • Avtobekor qilish — komponent kompozitsiyadan chiqqanda koroutin avtomatik bekor qilinadi.
  • Asinxronlik — blok CoroutineScope-da Dispatchers.Main dispetcheri bilan bajariladi.
  • Ma'lumotlarni yuklash — odatiy stsenariy: ekran birinchi marta paydo bo'lganda tarmoqdan yuklash.

Jetpack Compose-da LaunchedEffect nima

LaunchedEffect — bu Jetpack Compose-dagi DisposableEffect, SideEffect, SnapshotEffect va rememberCoroutineScope bilan birga beshta side-effect API-dan biridir. Uning o'ziga xos xususiyati — kodni composable-elementning hayotiy sikliga bog'langan asinxron koroutin kontekstida bajarishdir. Oddiy callback-funksiyalardan farqli o'laroq, LaunchedEffect UI-ni bloklamaydi va tarmoq so'rovlari yoki kechikishni kutish kabi uzoq muddatli operatsiyalarni bajarishi mumkin.

Ichki LaunchedEffect kompozitsiya tomonidan taqdim etilgan CoroutineScope-dan foydalanadi. Bu scope composable-element kompozitsiyani tark etganda avtomatik bekor qilinadi. Bunday bog'lanish ekran yopilgandan keyin hech qanday koroutin ishlashni davom ettirmasligini kafolatlaydi — bu ViewModel yoki Application scope-dagi global koroutinlardan asosiy farqdir.

Android Developers Blog (2025) ma'lumotlariga ko'ra, LaunchedEffect Compose dunyosida LiveData-observer naqshini almashtirish uchun maxsus ishlab chiqilgan. LiveData-ga observeAsState orqali obuna bo'lish va obunani alohida boshqarish o'rniga, dasturchilar Flow-da collectAsState bilan LaunchedEffect-dan foydalanadilar, bu esa hayotiy siklini yanada bashorat qilish mumkin bo'lgan boshqarishni ta'minlaydi va aniq bekor qilmasdan obunalarga xos xotira oqishlarini bartaraf etadi.

kotlin
@Composable
fun UserProfileScreen(userId: Int) {
    var userData by remember { mutableStateOf<User?>(null) }
    
    LaunchedEffect(userId) {
        val result = userRepository.fetchUser(userId)
        userData = result
    }
    
    // userData asosida interfeys
}

LaunchedEffect kalitlar bilan qanday ishlaydi

LaunchedEffect-ning eng muhim mexanizmi — kalitlar tizimidir. Funktsiyaning birinchi parametri — vararg keys: Any? — effekt qachon qayta ishga tushirilishi kerakligini aniqlaydi. LaunchedEffect avvalgi kalit qiymatlarini saqlaydi va har bir rekompozitsiyada ularni yangilari bilan solishtiradi. Agar kamida bitta kalit o'zgargan bo'lsa (equals() orqali), joriy koroutin bekor qilinadi va yangisi ishga tushiriladi.

Agar kalit, masalan, userId bo'lsa, foydalanuvchi identifikatori o'zgarganda LaunchedEffect avtomatik ravishda joriy so'rovni bekor qiladi va yangilangan userId bilan yangisini ishga tushiradi. Bu dasturchini oldingi so'rovni qo'lda bekor qilish va ma'lumotlarning dolzarbligini tekshirishdan ozod qiladi — hamma narsa kalitlar orqali deklarativ boshqariladi. Bunday yondashuv Jetpack Compose-ning reaktiv paradigmasiga mos keladi.

Muhim qoida: agar kalit sifatida konstanta uzatilsa — LaunchedEffect(Unit) — effekt klassik Android-dagi onStart yoki onResume analogi kabi kompozitsiyaga kirganda faqat bir marta bajariladi. Agar kalitlar uzatilmasa — LaunchedEffect(Unit) — effekt bir marta ishlaydi. Agar bo'sh qavslar uzatilsa — LaunchedEffect kompilyatsiya qilinmaydi, chunki kalitlar majburiy parametrdir.

kotlin
// Ekran paydo bo'lganda bir martalik bajarish
LaunchedEffect(Unit) {
    analytics.logScreenView("Profile")
}

// userId o'zgarganda qayta ishga tushirish
LaunchedEffect(userId) {
    loadUserData(userId)
}

// Bir nechta kalitlar
LaunchedEffect(userId, filter, sortOrder) {
    fetchFilteredData(userId, filter, sortOrder)
}

LaunchedEffect va DisposableEffect o'rtasidagi farq

Ikkala API ham Jetpack Compose-da side effects-ga tegishli bo'lsa-da, LaunchedEffect va DisposableEffect tubdan farqli vazifalarni hal qiladi. LaunchedEffect kalitlar bo'yicha qayta ishga tushirish imkoniyati bilan asinxron koroutinlar uchun mo'ljallangan, DisposableEffect esa koroutinsiz sinxron sozlash va resurslarni tozalash operatsiyalari uchundir.

Asosiy farq — onDispose-ning DisposableEffect-da mavjudligi. LaunchedEffect-da aniq tozalash bloki yo'q: koroutinni bekor qilish kalit o'zgarganda yoki kompozitsiyadan chiqishda avtomatik sodir bo'ladi, ammo dasturchi bu bekor qilish paytida o'z kodini kirita olmaydi. DisposableEffect esa kompozitsiyadan chiqishda kafolatlangan holda bajariladigan onDispose blokini ta'minlaydi, bu mahalliy resurslarni bo'shatish uchun juda muhimdir.

XususiyatLaunchedEffectDisposableEffect
BajarilishAsinxron (koroutin)Sinxron
onDisposeYo'q (koroutinni avtobekor qilish)Ha (aniq tozalash bloki)
KalitlarEski koroutinni bekor qilish + qayta ishga tushirishonDispose bajarilishi + qayta ishga tushirish
Odatiy qo'llanilishiTarmoq so'rovlari, Flow obunalari, taymerlarBroadcastReceiver, sensorlar, mahalliy listenerlar
Chiqishda bekor qilishAvtomatikonDispose orqali

Google maqolasi „Compose Side Effects: Deep Dive” (2025) ga ko'ra, LaunchedEffect va DisposableEffect o'rtasidagi to'g'ri tanlov resurs turiga qarab belgilanadi: agar operatsiya bekor qilish imkoniyati bo'lgan koroutin bo'lsa — LaunchedEffect-dan foydalaning. Agar resurs aniq close(), unregister() yoki dispose() chaqiruvini talab qilsa — DisposableEffect-dan foydalaning.

LaunchedEffect orqali ma'lumotlarni yuklash

LaunchedEffect-dan eng ko'p qo'llaniladigan stsenariy — ekran ochilganda ma'lumotlarni yuklash. Naqsh oddiy: LaunchedEffect ichida repository yoki UseCase-ning suspend-funksiyasi chaqiriladi, natija state o'zgaruvchisiga tayinlanadi va UI avtomatik qayta chiziladi. LaunchedEffect ekran qayta ochilganda (masalan, orqaga qaytganda) agar kalitlar o'zgargan bo'lsa, yuklash qayta bajarilishini kafolatlaydi.

Yuklash holatlarini ko'rsatish uchun uchlik holatlardan foydalaniladi: Loading, Success, Error. LaunchedEffect try-catch bilan o'raladi va muvaffaqiyatli bo'lganda state = Success(data), xato bo'lganda esa state = Error(exception) o'rnatiladi. UI state-ga reaksiya bildiradi va tegishli ekranni ko'rsatadi: shimmer-yuklagich, ma'lumotlar yoki qayta urinish tugmasi bilan xato ekrani.

Agar aylantirishda ma'lumotlarni yuklash talab qilinsa (pagination), LaunchedEffect LazyColumn va LazyListState bilan birlashtiriladi: ro'yxat oxiriga yetganda LaunchedEffect kaliti yangilanadi (masalan, sahifa hisoblagichi), bu esa keyingi ma'lumotlar qismining yuklanishini tetiklaydi.

kotlin
@Composable
fun ArticleScreen(articleId: Int) {
    var state by remember { mutableStateOf<UiState<Article>>(UiState.Loading) }
    
    LaunchedEffect(articleId) {
        state = UiState.Loading
        state = try {
            UiState.Success(articleRepository.fetch(articleId))
        } catch (e: Exception) {
            UiState.Error(e)
        }
    }
    
    when (val s = state) {
        is UiState.Loading -> ShimmerPlaceholder()
        is UiState.Success -> ArticleContent(s.data)
        is UiState.Error -> ErrorScreen(s.error) 
            { // onRetry callback (state updates) }
    }
}

Kalitlarni boshqarish va qayta ishga tushirish

LaunchedEffect kalitlaridan to'g'ri foydalanish — effektlar bilan samarali ishlashning kalitidir (burada so'z o'yini mohiyatni aks ettiradi). Agar kalit tez-tez o'zgarib turadigan mutable qiymat bo'lsa (masalan, har bir belgi kiritilishida qidiruv so'rovi matni), har bir belgi oldingi koroutinni bekor qiladi va yangisini ishga tushiradi. Kechikish bilan qidirish uchun bu ortiqcha — koroutin ichida debounce ishlatish yaxshiroqdir.

Debounce-ni LaunchedEffect ichida amalga oshirish uchun asosiy harakatni bajarishdan oldin delay() dan foydalaning. Masalan, qidirishda: LaunchedEffect(query) har bir query o'zgarishida ishga tushiriladi, ammo so'rovni bajarishdan oldin delay(500) turadi. Agar foydalanuvchi 500 ms o'tmasdan keyingi belgini kiritsa, koroutin bekor qilinadi (kalit o'zgarishi tufayli) va yangisi ishga tushiriladi — shunday qilib, so'rov faqat kiritishda 500 ms pauzadan keyin yuboriladi.

Yana bir texnika — kalit sifatida sealed class dan foydalanish. Bu effekt qachon qayta ishga tushirilishi kerakligini aniq nazorat qilish imkonini beradi. Masalan, kalit-o'ramchi identifikator va majburiy yangilash bayrog'ini o'z ichiga oladi: bayroq false dan true ga o'zgarganda LaunchedEffect identifikator o'zgarmagan bo'lsa ham qayta ishga tushiriladi. Bunday naqsh pull-to-refresh uchun qulaydir.

kotlin
// Debounce 500ms bilan qidirish
LaunchedEffect(searchQuery) {
    delay(500)
    searchResults.value = repository.search(searchQuery)
}

// Majburiy yangilash bilan pull-to-refresh
data class RefreshKey(val id: Int, val refreshTrigger: Int)
var refreshTrigger by remember { mutableIntStateOf(0) }

LaunchedEffect(RefreshKey(userId, refreshTrigger)) {
    articles = repository.loadUserArticles(userId)
}

LaunchedEffect bilan odatiy xatolar

Birinchi va eng keng tarqalgan xato — LaunchedEffect-ni kalitsiz ishlatish. Agar LaunchedEffect { ... } argumentlarsiz yozilsa, koroutin har bir rekompozitsiyada qayta ishga tushiriladi, bu esa cheksiz so'rovlar siklini keltirib chiqaradi. LaunchedEffect kamida bitta kalitni talab qiladi — odatda bir martalik bajarish uchun Unit.

Ikkinchi xato — LaunchedEffect-ni collect qilmasdan Flow-ga obuna bo'lish uchun ishlatishga urinish. Agar LaunchedEffect ichida Flow-da collect chaqirilsa, koroutin Flow tugashini kutib to'xtaydi (StateFlow holatida bu hech qachon sodir bo'lmaydi) va onDispose bloki normal tugallana olmaydi. To'g'ri yondashuv — collectLatest dan foydalanish, u yangi qiymat kelganda oldingi kolleksiyani bekor qiladi.

Uchinchi xato — ichma-ich ob'yektlarni kalit sifatida uzatish. Agar kalit o'zgaruvchan maydonlari bo'lgan (var) data class bo'lsa, LaunchedEffect o'zgarishni tanimasligi mumkin, chunki Compose taqqoslash uchun equals() dan foydalanadi va u var-maydonlar uchun oldindan aytib bo'lmaydigan ishlashi mumkin. Har doim LaunchedEffect kalitlari sifatida immutable ob'yektlardan (val) yoki primitivlardan foydalaning.

Tez-tez beriladigan savollar

LaunchedEffect-ga kalit uzatilmasa nima bo'ladi?

Kalitlar uzatilmasa, LaunchedEffect kompilyatsiya qilinmaydi — Kotlin vararg parametrlari uchun kamida bitta argument talab qiladi. Kompozitsiyaga kirishda bir martalik bajarish uchun LaunchedEffect(Unit) dan foydalaning yoki o'zgarganda effekt qayta ishga tushirilishi kerak bo'lgan aniq qiymatlarni uzating.

LaunchedEffect xotira oqishiga sabab bo'lishi mumkinmi?

Yo'q, LaunchedEffect composable kompozitsiyadan chiqqanda koroutinni avtomatik bekor qiladi, bu xotira oqishining oldini oladi. Biroq, agar LaunchedEffect ichidagi koroutin yopilish orqali Activity yoki Context-ga havolani ushlab tursa, xotira oqishi mumkin — ViewModel-dagi uzoq muddatli operatsiyalar uchun viewModelScope dan foydalaning.

LaunchedEffect va rememberCoroutineScope o'rtasidagi farq nima?

LaunchedEffect kompozitsiyaga kirishda koroutinni avtomatik bajaradi, kalitlarga bog'langan holda. rememberCoroutineScope koroutinlarni qo'lda ishga tushirish uchun scope-ni taqdim etadi, masalan, onItemClick ga javoban. Avtomatik side effects uchun LaunchedEffect-dan va foydalanuvchi hodisalari bo'yicha koroutinlarni ishga tushirish uchun rememberCoroutineScope-dan foydalaning.

Nega LaunchedEffect rekompozitsiyada bir necha marta bajariladi?

Agar LaunchedEffect kaliti beqaror tur bo'lsa (masalan, var yoki equals() bo'lmagan sinf), Compose qiymat o'zgarmaganligini tanimasligi mumkin va effektni har bir rekompozitsiyada qayta ishga tushiradi. Yechim: barqaror turlardan (primitivlar, stringlar, val maydonlari bo'lgan data class) foydalaning yoki mutable qiymatlarni remember-ga o'rang.

LaunchedEffect-ni qo'lda qanday to'xtatish mumkin?

LaunchedEffect-ni tashqaridan to'xtatishning to'g'ridan-to'g'ri usuli yo'q — boshqarish kalitlar orqali amalga oshiriladi. Joriy koroutinni bekor qilish uchun kalitni o'zgartiring. Agar koroutinning hayotiy siklini to'liq nazorat qilish kerak bo'lsa, Job bilan rememberCoroutineScope-dan foydalaning va hodisa yoki holat o'zgarishida qo'lda job.cancel() ni chaqiring.

Xulosa

  • LaunchedEffect — asinxron koroutinlarni composable hayotiy sikliga bog'lash uchun Jetpack Compose side-effect API.
  • Kalitlar — kalitlar bo'yicha qayta ishga tushirish tizimi: kalit o'zgarishi joriy koroutinni bekor qiladi va yangilangan parametrlar bilan yangisini ishga tushiradi.
  • Avtobekor qilish — koroutin composable kompozitsiyadan chiqqanda avtomatik bekor qilinadi, xotira oqishining oldini oladi.
  • Ma'lumotlarni yuklash — odatiy naqsh: LaunchedEffect(key) bilan Loading, Success, Error holatlarini boshqargan holda tarmoqdan ma'lumotlarni yuklash.
  • Debounce — LaunchedEffect ichida delay() orqali amalga oshiriladi: kechikish tugamagan holda kalit o'zgarganda koroutin bekor qilinadi.
  • Flow obunasi — LaunchedEffect ichida Flow-ni to'g'ri qayta ishlash uchun collect o'rniga collectLatest dan foydalaning.
  • Barqaror kalitlar — bashorat qilish mumkin bo'lgan xatti-harakatlar uchun kalit sifatida faqat immutable turlardan (val, primitivlar, data class) 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