Deferred Navigation — bu nima, tamoyillari va amalga oshirish

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

Deferred Navigation — bu kechiktirilgan navigatsiya namunasi bo'lib, unda keyingi ekranga o'tish asinxron amaliyot tugagandan so'ng amalga oshiriladi, foydalanuvchi harakati paytida emas. Android Developers (2024) ma'lumotlariga ko'ra, deferred navigation navigatsiya va ma'lumotlarni yuklash o'rtasidagi poyga holatidan qochishga imkon beradi, shuningdek push-bildirishnomalar va Deeplinkdan o'tishlarni qayta ishlashni soddalashtiradi. Asosiy farq — marshrut barcha kerakli ma'lumotlar mavjud bo'lgandan keyin hisoblanadi.

Asosiy fikrlar

  • Deferred Navigation — kechiktirilgan navigatsiya, unda o'tish asinxron amaliyotlar tugagandan so'ng amalga oshiriladi
  • To'g'ridan-to'g'ri navigatsiya o'tishni darhol boshqaradi, deferred — ma'lumotlarni kutadi
  • Oddiy stsenariylar: avtorizatsiya, Deeplink, push-bildirishnomalar, konfiguratsiyani yuklash
  • Android-da Navigation Component orqali chaqiruvlar va StateFlow bilan amalga oshiriladi
  • iOS-da Combine yoki async/await navigatsiya koordinatori bilan ishlatiladi

Deferred Navigation nima

Deferred Navigation — bu arxitektura namunasi bo'lib, unda navigatsiya qarori barcha kerakli ma'lumotlar mavjud bo'lgunga qadar kechiktiriladi. To'g'ridan-to'g'ri o'tishdan farqli o'laroq, foydalanuvchi tugmani bosadi va darhol yangi ekranga o'tadi, deferred navigation hodisa-triggerni va haqiqiy o'tishni ajratadi, ular orasiga asinxron amaliyot qo'shadi.

Arxitektura nuqtai nazaridan, Deferred Navigation holat o'zgarishiga asoslanadi: tugmani bosish asinxron jarayonni boshlaydi va uning natijasiga obuna bo'lish navigatsiyani ishga tushiradi. Bu, ayniqsa, MVVM yoki MVI arxitekturasiga ega ilovalarda muhim, bunda ViewModel holatni boshqaradi, View (Activity, Fragment, SwiftUI View) esa o'zgarishlarga obuna bo'ladi va o'tish bilan reaksiya beradi. Bunday yondashuv UI va navigatsiya mantig'i o'rtasidagi to'g'ridan-to'g'ri bog'liqlikni yo'q qiladi.

Google I/O 2023 ma'lumotlariga ko'ra, deferred navigation tarmoq so'rovi natijasiga, avtorizatsiya tekshiruviga, konfiguratsiyani yuklashga yoki ruxsatnomalarga bog'liq bo'lgan barcha stsenariylar uchun tavsiya etiladi. Ushbu namuna, shuningdek, Deeplinkni qayta ishlashda majburiydir, bunda ilova avval ishga tushishi, ildiz ekranini yuklashi va keyin maqsadli marshrutga o'tishi kerak.

Kechiktirilgan navigatsiya qachon kerak

Deferred Navigation to'g'ridan-to'g'ri o'tish ekranning noto'g'ri holatiga yoki yuklash xatolariga olib keladigan stsenariylarda qo'llaniladi. Kechiktirilgan navigatsiya majburiy bo'lgan to'rtta asosiy holatni ko'rib chiqamiz.

Avtorizatsiya va autentifikatsiya

Agar foydalanuvchi himoyalangan kontentni bossa, ilova avval kirish tokenini tekshirishi kerak. To'g'ridan-to'g'ri navigatsiya kontent ekraniga token muddati tugagan bo'lsa, bo'sh ekran yoki 401 xatosiga olib keladi. Deferred navigation tokenni tekshiradi va faqat muvaffaqiyatli bo'lganda maqsadli ekranga o'tadi. Muvaffaqiyatsizlikda kirish ekraniga yo'naltiradi.

Deeplinkni qayta ishlash

Ilova tashqi havola orqali ochilganda, avval ildiz ekranini yuklash, navigatsiya holatini tiklash va keyin Deeplink orqali o'tishni amalga oshirish kerak. Ildiz kontekstisiz maqsadli ekranga to'g'ridan-to'g'ri navigatsiya anomaliyalarga olib keladi: bo'sh navigatsiya steki yoki buzilgan back stack.

Kontentli push-bildirishnomalar

Push-bildirishnomani bosganda ilova uch holatda bo'lishi mumkin: yopiq, fonda yoki faol. Deferred Navigation ilova holatini aniqlaydi, kerakli kontentni yuklaydi va keyin maqsadli ekranni ko'rsatadi. iOS UNNotificationContentExtension orqali ushbu stsenariyni qayta ishlashga imkon beradi.

Dinamik feature flag

Ekran funksionalligi serverdagi feature flag bilan boshqarilsa, deferred navigation avval konfiguratsiyani so'rashga va keyin ekranni ko'rsatishga imkon beradi. Agar funksiya o'chirilgan bo'lsa, foydalanuvchi bo'sh ekran o'rniga muqobil kontent yoki placeholder ko'radi.

StsenariyTo'g'ridan-to'g'ri navigatsiyaDeferred Navigation
AvtorizatsiyaToken muddati tugaganda bo'sh ekranKirishga yo'naltirish
DeeplinkBuzilgan back stackTo'g'ri navigatsiya steki
PushKontekstsiz yuklashMa'lumotlar o'tishdan oldin tayyor
Feature flagMavjud bo'lmagan funksiyani ko'rsatishPlaceholder yoki muqobil

Deferred Navigation vs to'g'ridan-to'g'ri navigatsiya

To'g'ridan-to'g'ri navigatsiya (direct navigation) — an'anaviy yondashuv bo'lib, unda o'tish hodisaga javoban darhol amalga oshiriladi. Foydalanuvchi tugmani bosadi va UI marshrutizatori darhol ekranni o'zgartiradi. Bu yondashuv sodda va bashorat qilinadigan, ammo server ma'lumotlari yoki shartlarni tekshirish kerak bo'lgan stsenariylarda cheklangan.

Deferred Navigation asinxron holat ko'rinishida qatlam qo'shadi. Foydalanuvchi hodisasi operatsiyani boshlaydi va natijaga obuna bo'lish navigatsiyani boshqaradi. Bu kod murakkabligini oshiradi, lekin moslashuvchanlik beradi: bir xil trigger yuklangan ma'lumotlarga qarab turli ekranlarga olib kelishi mumkin.

Ikki yondashuv o'rtasidagi tanlov talablarga bog'liq: agar ekranni ko'rsatish uchun asinxron ma'lumotlar kerak bo'lmasa — to'g'ridan-to'g'ri navigatsiyadan foydalaning. Agar ekran so'rov natijasiga, avtorizatsiyaga yoki tashqi shartlarga bog'liq bo'lsa — deferred navigation majburiydir. Gibrid yondashuv, o'tishlarning bir qismi to'g'ridan-to'g'ri va bir qismi kechiktirilgan — ishlab chiqarish ilovalarida eng keng tarqalgan amaliyotdir.

Android-da amalga oshirish: Navigation Component va ViewModel

Android Jetpack Deferred Navigation-ni arxitektura darajasida amalga oshirish mexanizmlarini taqdim etadi. Asosiy g'oya — ViewModel holatni boshqaradi, Activity yoki Fragment esa o'zgarishlarga obuna bo'ladi va NavController orqali navigatsiyani ishga tushiradi.

StateFlow bilan Deferred Navigation

StateFlow Kotlin coroutines-da deferred navigation uchun ideal vositadir. ViewModel StateFlow-ni navigatsiya hodisasi bilan yangilaydi, Activity esa uni kuzatadi va o'tishni amalga oshiradi. Hodisa qayta ishlanganda StateFlow tozalanadi, qayta navigatsiyaning oldini oladi.

kotlin
class MainViewModel : ViewModel() {
    private val _navigation = MutableSharedFlow<NavigationEvent>()
    val navigation: SharedFlow<NavigationEvent> = _navigation

    fun onDeepLinkReceived(link: String) {
        viewModelScope.launch {
            val data = resolveDeepLink(link)
            _navigation.emit(NavigationEvent.GoToScreen(data))
        }
    }
}

NavController bilan Deferred Navigation

Activity da navigatsiyaga obuna bo'lish ViewModel-dan marshrut bilan NavController-ni ishga tushiradi. Ekran aylanishida qayta navigatsiyaning oldini olish uchun NavigationEventWrapper ishlatiladi, u hodisani faqat bir marta qayta ishlaydi. Jetpack Navigation 2.7+ argumentlarni xavfsiz uzatish uchun Safe Args-ni qo'llab-quvvatlaydi.

kotlin
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val vm: MainViewModel by viewModels()
        repeatOnLifecycle(Lifecycle.State.STARTED) {
            vm.navigation.collect { event ->
                when (event) {
                    is NavigationEvent.GoToScreen ->
                        findNavController(R.id.nav_host)
                            .navigate(event.route)
                }
            }
        }
    }
}

iOS-da amalga oshirish: Coordinator Pattern va Combine

iOS Android Jetpack-ga o'xshash o'rnatilgan Navigation Component-ga ega emas, shuning uchun dasturchilar Deferred Navigation-ni Coordinator Pattern orqali Combine yoki async/await bilan birgalikda amalga oshiradilar. Coordinator ekranlar to'plamini boshqaradi va yuklangan ma'lumotlar asosida navigatsiya qarorlarini qabul qiladi.

Combine bilan Coordinator

Coordinator — ViewController-lar o'rtasida navigatsiyani boshqaradigan ob'ekt. Combine bilan birgalikda ViewModel hodisalarni PassthroughSubject orqali nashr etadi, Coordinator esa ularga obuna bo'ladi va o'tishni amalga oshiradi. Bunday yondashuv UI-ni navigatsiya mantig'idan butunlay ajratadi va Apple-ning ilova arxitekturasi bo'yicha tavsiyalariga mos keladi.

swift
final class AppCoordinator {
    private var cancellables = Set<AnyCancellable>()

    func start(viewModel: MainViewModel) {
        viewModel.$navigationDestination
            .compactMap { $0 }
            .sink { [weak self] destination in
                self?.navigateTo(destination)
            }
            .store(in: &cancellables)
    }
}

async/await bilan Deferred Navigation

Swift 5.5 structured concurrency-ni taqdim etdi, bu Combine-siz async/await orqali kechiktirilgan navigatsiyani amalga oshirishga imkon beradi. ViewModel ma'lumotlarni yuklagandan so'ng marshrutni qaytaruvchi async-funksiyani taqdim etadi. Coordinator bu funksiyani Task-da chaqiradi va olingan marshrut bo'yicha o'tishni amalga oshiradi.

swift
class AuthViewModel: ObservableObject {
    func resolveDeeplink(_ url: URL) async -> AppRoute? {
        guard let token = await AuthService.shared.getValidToken() else { return .login }
        return await DeeplinkRouter.resolve(url, token: token)
    }
}

// Coordinator-da:
Task {
    if let route = await viewModel.resolveDeeplink(url) {
        navigateTo(route)
    }
}

Oddiy xatolar va best practices

Deferred Navigation asinxron stsenariylarni qayta ishlashni soddalashtiradi, lekin holatni boshqarishga intizomli yondashishni talab qiladi. Deferred navigation-ni joriy etishda dasturchilar yo'l qo'yadigan asosiy xatolarni ko'rib chiqamiz.

Xato: initsializatsiya tugamagan holda navigatsiya

Eng keng tarqalgan xato — ildiz ekran to'liq initsializatsiya qilinmagan va NavController yoki Coordinator o'tishga tayyor bo'lmaganida deferred navigation amalga oshirishga urinish. Android-da bu IllegalStateException-ga, iOS-da esa noaniq UI holatiga olib keladi. Yechim — navigatsiyani boshlashdan oldin komponentning hayot aylanishi STARTED yoki RESUMED holatida ekanligiga ishonch hosil qiling.

Xato: ekranga qaytganda qayta navigatsiya

Agar StateFlow yoki Subject hodisani qayta ishlashdan keyin tozalamasa, oldingi ekranga qaytganda foydalanuvchi avtomatik ravishda yana o'sha ekranga yo'naltirilishi mumkin. Android-da replay=0 bo'lgan SharedFlow yoki iOS-da qayta ishlashdan keyin nil bo'lgan CurrentValueSubject dan foydalaning, navigatsiya hodisasi faqat bir marta ishga tushsin.

Best Practice: yagona NavController yoki Coordinator

Ilovadagi barcha navigatsiya uchun bitta markaziy komponentdan foydalaning. Har bir Activity, Fragment yoki ViewController o'z navigatsiya boshqaruvchisiga ega bo'lsa, ilovaning turli qismlari o'rtasida deferred navigation tartibsiz bo'ladi. Yagona Coordinator navigatsiya stsenariylarini disk raskadrovka qilish va test qilishni osonlashtiradi.

Best Practice: kechiktirilgan navigatsiya stsenariylarini test qilish

Deferred Navigation to'g'ridan-to'g'ri navigatsiyadan ko'ra test qilish qiyinroq, chunki asinxron operatsiyalar vaqt omilini keltiradi. Android-da TestDispatcher (kotlinx-coroutines-test) va iOS-da XCTestExpectation dan foydalanib ma'lumotlarni yuklashni simulyatsiya qiling va navigatsiya kutilgan marshrut bo'ylab amalga oshirilayotganini tekshiring. Har bir stsenariyni izolyatsiya qilingan holda testlash uchun avtorizatsiya va deeplink xizmatlarini mock qiling.

Tez-tez beriladigan savollar

Deferred Navigation Deep Link-dan nima bilan farq qiladi?

Deferred Navigation — kechiktirilgan o'tish namunasi bo'lib, har qanday asinxron stsenariyda qo'llanilishi mumkin. Deep Link deferred navigation uchun triggerlardan biridir, ammo yagona emas. Avtorizatsiya va feature flaglar ham kechiktirilgan navigatsiyadan foydalanadi.

Deferred va direct navigationni birlashtirish mumkinmi?

Ha, ko'pchilik ilovalar gibrid yondashuvdan foydalanadi. Mahsulot ro'yxati ekrani (asinxron bog'liqliklarsiz) to'g'ridan-to'g'ri navigatsiyadan foydalanishi mumkin, ma'lumotlarni yuklash bilan detal ekrani esa deferred. Bo'linish aniq ekran arxitekturasi bilan belgilanadi.

Deferred navigationda race condition dan qanday qochish mumkin?

Ishlating Android-da replaysiz SharedFlow va iOS-da buferlashsiz combineLatest. Yangi triggerda oldingi obunalarni bekor qiling. Bu faqat oxirgi navigatsiya hodisasi qayta ishlanishini kafolatlaydi.

Jetpack Compose deferred navigationni qo'llab-quvvatlaydimi?

Ha, Compose-da deferred navigation ViewModel StateFlow-iga obuna bo'lish va LaunchedEffect ichida NavController.navigate chaqirish orqali amalga oshiriladi. Google deferred stsenariylar uchun Navigation Compose-ni hodisa modeli bilan ishlatishni tavsiya qiladi.

Kichraytirilgan ilovada deferred navigationni qanday boshqarish kerak?

Kechiktiring navigatsiyani ilova yana faol bo'lgunga qadar. Android-da hodisalarni filtrlash uchun Lifecycle.State.STARTED dan foydalaning. iOS-da Combine yoki async/await blokida UIApplication.State ni tekshiring.

Xulosa

  • Deferred Navigation — o'tish asinxron amaliyot tugagandan so'ng amalga oshiriladigan namuna
  • Asosiy stsenariylar: avtorizatsiya, Deeplink, push-bildirishnomalar, feature flaglar
  • StateFlow/SharedFlow Android-da va Combine/async-await iOS-da — amalga oshirish vositalari
  • Deferred Navigation to'g'ridan-to'g'ridan farqli o'laroq asinxron yuklashda poyga holatiga olib kelmaydi
  • Navigation Component Android-da va Coordinator Pattern iOS-da — asosiy arxitekturalar
  • Yagona NavController/Coordinator izchil navigatsiya uchun majburiydir
  • Test deferred navigation asinxron xizmatlar uchun TestDispatcher va mocklarni talab qiladi

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