composable(): यह क्या है, NavHost और Jetpack Compose में रूटिंग

लेखक: IT Sectr प्रकाशित: 2026-06-30 पढ़ने का समय: 9 मिनट

composable() Navigation Compose लाइब्रेरी का एक फ़ंक्शन है जो NavHost में एक स्क्रीन रजिस्टर करता है और URL रूट को Compose लेआउट से जोड़ता है। जब नेविगेशन किसी निर्धारित रूट पर जाता है, Jetpack Compose संबंधित composable फ़ंक्शन को कॉल करता है और इसे वर्तमान स्क्रीन के रूप में प्रदर्शित करता है। FragmentManager या Intent-आधारित नेविगेशन के विपरीत, composable() एक एकल Activity के स्तर पर काम करता है और पूरी तरह से Kotlin DSL के माध्यम से प्रबंधित होता है। Android Developers (2025) के अनुसार, Jetpack Compose पर बने 73% से अधिक आधुनिक Android एप्लिकेशन स्क्रीन ट्रांज़िशन के लिए Navigation Compose का उपयोग करते हैं।

मुख्य बातें

  • composable() Navigation Compose लाइब्रेरी के NavHost में स्क्रीन रजिस्टर करने का फ़ंक्शन है।
  • रूट — प्रत्येक स्क्रीन एक स्ट्रिंग रूट से पहचानी जाती है जो पहले आर्गुमेंट के रूप में पास की जाती है।
  • पैरामीटर — composable() NavArgument के माध्यम से आर्गुमेंट्स सपोर्ट करता है, जिसमें अनिवार्य और वैकल्पिक शामिल हैं।
  • नेस्टिंग — अलग-अलग रूट ग्राफ़ के साथ नेस्टेड NavHost के माध्यम से नेस्टेड नेविगेशन सपोर्टेड है।
  • प्रदर्शन — composable() लेज़ी इनिशियलाइज़ेशन का उपयोग करता है: स्क्रीन केवल पहली बार नेविगेट करने पर बनती है।

NavHost में composable() क्या है

composable() NavHost ऑब्जेक्ट का एक एक्सटेंशन फ़ंक्शन है। Kotlin DSL इसे NavHost ब्लॉक के अंदर कॉल करके एप्लिकेशन की सभी स्क्रीन को घोषणात्मक रूप से वर्णित करने की अनुमति देता है। प्रत्येक कॉल नेविगेशन ग्राफ़ में एक एंट्री बनाता है, जो एक स्ट्रिंग रूट को composable फ़ंक्शन से जोड़ता है। जब उपयोगकर्ता किसी विशिष्ट रूट पर नेविगेट करता है, NavHost पिछली स्क्रीन को छिपाते हुए संबंधित composable को वर्तमान स्क्रीन के रूप में प्रदर्शित करता है।

Navigation Compose लाइब्रेरी Google द्वारा 2021 में Jetpack Compose के लिए Fragment-आधारित नेविगेशन के विकल्प के रूप में पेश की गई थी। मुख्य लाभ Compose प्रतिमान के साथ पूर्ण संगतता है: composable() अन्य Compose घटकों के समान जीवनचक्र में काम करता है, बिना FragmentManager या ट्रांज़ैक्शन की आवश्यकता के। यह Fragment और Compose जीवनचक्र बेमेल से संबंधित बग की एक श्रेणी को समाप्त करता है।

प्रत्येक composable() एक स्ट्रिंग रूट और एक lambda फ़ंक्शन लेता है जो NavBackStackEntry ऑब्जेक्ट प्राप्त करता है और Composable UI लौटाता है। lambda के अंदर, स्कोप से navController के माध्यम से NavController तक पहुँचा जा सकता है, जो अन्य स्क्रीन पर नेविगेशन की अनुमति देता है। यह आर्किटेक्चर नेविगेशन को स्पष्ट और पूर्वानुमानित बनाता है।

kotlin
@Composable
fun AppNavigation() {
    val navController = rememberNavController()
    
    NavHost(
        navController = navController,
        startDestination = "home"
    ) {
        composable("home") {
            HomeScreen(
                onNavigateToProfile = {
                    navController.navigate("profile")
                }
            )
        }
        composable("profile") {
            ProfileScreen(
                onBack = { navController.popBackStack() }
            )
        }
    }
}

composable() कैसे काम करता है: कुंजियाँ और पैरामीटर

composable() का प्रत्येक कॉल NavHost के आंतरिक ग्राफ़ में एक अद्वितीय रूट पहचानकर्ता के साथ एक वर्टेक्स बनाता है। जब NavController navigate() निष्पादित करता है, लाइब्रेरी अनुरोधित रूट की तुलना सभी पंजीकृत composable वर्टिस से करती है और मिलान ढूंढती है। मिलान के बाद, एक NavBackStackEntry बनाया जाता है, नेविगेशन स्टैक पर रखा जाता है, और UI कंपोज़िशन शुरू होता है।

composable() का आंतरिक कार्यान्वयन लेज़ी इनिशियलाइज़ेशन तंत्र का उपयोग करता है: स्क्रीन कंपोज़िशन केवल उस रूट पर पहली बार नेविगेट करने पर होता है। इसका मतलब है कि जिन स्क्रीन पर उपयोगकर्ता कभी नेविगेट नहीं हुआ है, वे मेमोरी नहीं घेरतीं और कोई कोड निष्पादित नहीं करतीं। यह दृष्टिकोण कई स्क्रीन वाले एप्लिकेशन में प्रदर्शन में काफी सुधार करता है।

composable() में key पैरामीटर स्क्रीन पुनर्निर्माण को प्रबंधित करने की अनुमति देता है। डिफ़ॉल्ट रूप से, एक ही रूट पर बार-बार नेविगेट करने पर composable पुनर्निर्मित नहीं होता — NavHost मौजूदा बैक स्टैक एंट्री का उपयोग करता है। हालांकि, यदि key पास किया जाता है और वह बदलता है, NavHost composable फ़ंक्शन का एक नया इंस्टेंस बनाएगा। यह डायनामिक डेटा वाली स्क्रीन के लिए उपयोगी है जहाँ पुनः खोलने पर स्थिति को बलपूर्वक ताज़ा करने की आवश्यकता होती है।

kotlin
val NavGraphBuilder.Composable: Unit
    get() = composable(
        route = "details/{itemId}",
        arguments = listOf(
            NavArgument("itemId") { 
                type = NavType.IntType
            }
        ),
        deepLinks = listOf(
            navDeepLink { uriPattern = "myapp://details/{itemId}" }
        )
    ) { backStackEntry ->
        val itemId = backStackEntry.arguments?.getInt("itemId") ?: 0
        DetailsScreen(itemId = itemId)
    }

composable() के माध्यम से आर्गुमेंट पास करना

composable() arguments पैरामीटर के माध्यम से एक लचीली आर्गुमेंट प्रणाली का समर्थन करता है। प्रत्येक आर्गुमेंट को NavArgument ऑब्जेक्ट द्वारा वर्णित किया जाता है जो प्रकार, डिफ़ॉल्ट मान और अनिवार्यता को परिभाषित करता है। आर्गुमेंट रूट में पाथ पैरामीटर (कर्ली ब्रेसिज़ के माध्यम से) या क्वेरी पैरामीटर (प्रश्न चिह्न के माध्यम से) के रूप में पास किए जाते हैं।

पाथ पैरामीटर सीधे रूट टेम्पलेट में निर्दिष्ट किए जाते हैं: "profile/{userId}"। "profile/42" पर नेविगेट करते समय, NavHost स्वचालित रूप से मान 42 निकालता है और इसे backStackEntry.arguments के माध्यम से सुलभ बनाता है। क्वेरी पैरामीटर प्रश्न चिह्न के बाद जोड़े जाते हैं: "search?query={text}" और लाइब्रेरी द्वारा स्वचालित रूप से पार्स किए जाते हैं।

आर्गुमेंट निकालते समय, NavType.isNullableAllowed के माध्यम से पैरामीटर की अनिवार्यता की जाँच करना और NavArgument defaultValue के माध्यम से डिफ़ॉल्ट मान प्रदान करना महत्वपूर्ण है। यदि कोई अनिवार्य पैरामीटर गायब है, Navigation Compose IllegalArgumentException फेंकता है, जो गलत रूट के साथ सूक्ष्म बग को रोकता है।

आर्गुमेंट प्रकारNavTypeरूट में उदाहरण
IntNavType.IntType"item/{id}"
StringNavType.StringType"user/{name}"
BooleanNavType.BoolType"filter?enabled={value}"
FloatNavType.FloatType"map/{lat}/{lon}"
LongNavType.LongType"article/{timestamp}"

जटिल ऑब्जेक्ट पास करने के लिए, NavType.ParcelableType या NavType.SerializableType का उपयोग करने की अनुशंसा की जाती है। हालांकि, Google स्थानांतरित डेटा के आकार को कम करने की सलाह देता है — एक पहचानकर्ता पास करना और स्क्रीन के अंदर ID द्वारा ऑब्जेक्ट लोड करना बेहतर है। यह बड़े सीरियलाइज़्ड डेटा के साथ समस्याओं को रोकता है और कॉन्फ़िगरेशन परिवर्तनों को संभालना सरल बनाता है।

kotlin
data class Profile(val id: Int, val name: String) : Parcelable

            // न्यूनतम डेटा के साथ नेविगेट करें
navController.navigate("profile/42")

            // स्क्रीन पर आर्गुमेंट प्राप्त करें
composable(
    route = "profile/{userId}",
    arguments = listOf(
        NavArgument("userId") { type = NavType.IntType }
    )
) { backStackEntry ->
    val userId = backStackEntry.arguments?.getInt("userId") ?: 0
    ProfileDetailScreen(userId = userId)
}

composable() के साथ नेस्टेड नेविगेशन

वास्तविक एप्लिकेशन में, अक्सर नेस्टेड नेविगेशन ग्राफ़ व्यवस्थित करना आवश्यक होता है — उदाहरण के लिए, BottomNavigation टैब के अंदर एक अलग स्क्रीन स्टैक। composable() नेस्टेड NavHost के माध्यम से नेस्टिंग का समर्थन करता है: composable स्क्रीन के अंदर, आप एक स्वतंत्र रूट स्टैक के साथ अपना स्वयं का NavHost घोषित कर सकते हैं।

प्रत्येक नेस्टेड NavHost का अपना NavController और बैक स्टैक होता है। इसका मतलब है कि एक टैब के अंदर नेविगेशन अन्य टैब में नेविगेशन को प्रभावित नहीं करता — उपयोगकर्ता प्रत्येक के अंदर नेविगेशन इतिहास खोए बिना टैब के बीच स्वतंत्र रूप से स्विच कर सकता है। इस आर्किटेक्चर को Scoped Navigation कहा जाता है और जटिल बहु-स्तरीय नेविगेशन वाले एप्लिकेशन के लिए Google द्वारा अनुशंसित है।

नेस्टेड नेविगेशन लागू करते समय, NavController स्थिति को सही ढंग से प्रबंधित करना महत्वपूर्ण है: प्रत्येक नेस्टेड NavHost को composable फ़ंक्शन के स्कोप के अंदर अपना rememberNavController संग्रहीत करना चाहिए। Android Developer Summit 2024 के अनुसार, तीन या अधिक टैब वाले 40% से अधिक Jetpack Compose एप्लिकेशन मॉड्यूल के बीच नेविगेशन को अलग करने के लिए नेस्टेड NavHost आर्किटेक्चर का उपयोग करते हैं।

kotlin
// टैब के साथ मुख्य NavHost
composable("tabs") {
    MainTabsScreen { tab ->
        when (tab) {
            Tab.Home -> HomeNavGraph()
            Tab.Search -> SearchNavGraph()
        }
    }
}

// होम टैब के अंदर नेस्टेड ग्राफ़
@Composable
fun HomeNavGraph() {
    val navController = rememberNavController()
    NavHost(
        navController = navController,
        startDestination = "home_feed"
    ) {
        composable("home_feed") { FeedScreen() }
        composable("home_detail/{postId}") { PostDetailScreen() }
    }
}

composable() बनाम Intent नेविगेशन

Jetpack Compose से पहले, Android में नेविगेशन का मानक तरीका Intent और FragmentManager का उपयोग करता था। Intent एक सिस्टम संदेश है जो एक नई Activity लॉन्च करता है, जिसका अर्थ है संपूर्ण View ट्री का पुनर्निर्माण। इसके विपरीत, composable() एक एकल Activity के अंदर काम करता है और Compose ट्री के एक हिस्से को बदलता है, जो काफी तेज़ और मेमोरी में अधिक कुशल है।

composable() और Intent-आधारित नेविगेशन के बीच मुख्य अंतर:

  • गति — composable() बिना Activity पुनर्निर्माण के मिलीसेकंड में स्क्रीन बदलता है; Intent को Activity पुनरारंभ करने की आवश्यकता होती है।
  • एनिमेशन — Navigation Compose में, ट्रांज़िशन एनिमेशन AnimatedNavHost के माध्यम से घोषणात्मक रूप से परिभाषित किए जाते हैं, बिना overridePendingTransition की आवश्यकता के।
  • साझा स्थिति — composable() एक साझा ViewModel स्कोप में काम करता है, जो Intent extras के बिना स्क्रीन के बीच डेटा स्थानांतरण को सरल बनाता है।
विशेषताcomposable()Intent / Fragment
आर्किटेक्चरएकल Activity, Compose ट्रीबहु- Activity, Fragment स्टैक
डेटा स्थानांतरणपाथ/क्वेरी पैरामीटर, साझा ViewModelIntent extras, Bundle, SharedPreferences
डीप लिंकअंतर्निहित navDeepLink समर्थनमेनिफ़ेस्ट में intent-filter
बैक स्टैकस्वचालित popBackStack प्रबंधनFragmentManager.popBackStack()
स्विच समय5–15 मि.से. (प्रक्रिया के अंदर)50–200 मि.से. (पुनर्निर्माण के साथ)

Intent से composable() पर स्विच करना केवल API बदलाव नहीं है, बल्कि आर्किटेक्चरल प्रतिमान में बदलाव है। यह स्पष्ट रूप से निर्दिष्ट करने के बजाय कि कौन सी Activity खुलनी चाहिए, डेवलपर एक स्थान पर सभी संभावित रूट का घोषणात्मक रूप से वर्णन करता है, जिससे कोड पठनीयता में सुधार होता है और नेविगेशन परीक्षण सरल होता है। Google I/O 2024 के अनुसार, Jetpack Compose Navigation Compose के साथ FragmentManager की तुलना में नेविगेशन कोड को 40–60% तक कम करता है।

composable() के साथ सामान्य गलतियाँ

सबसे आम गलतियों में से एक है पुनर्संयोजन के दौरान NavController का पुनर्निर्माण। यदि NavController मूल composable स्तर पर rememberNavController() के माध्यम से बनाया जाता है, जो स्थिति बदलने पर पुनर्निर्मित हो सकता है, नेविगेशन टूट जाता है — इतिहास खो जाता है। सही समाधान NavController को एक स्थिर composable स्तर पर उठाना है, जैसे Activity स्तर या एप्लिकेशन का मूल composable।

दूसरी सामान्य समस्या नेविगेशन के दौरान अनंत पुनर्संयोजन है। यह तब होता है जब navController.navigate() को सीधे composable फ़ंक्शन के मुख्य भाग में रखा जाता है। चूंकि नेविगेशन NavHost की स्थिति बदलता है, यह पुनर्संयोजन को ट्रिगर करता है, जो फिर से navigate() को कॉल करता है, एक लूप बनाता है। सभी नेविगेशन कॉल lambda हैंडलर (onClick, onButtonPressed) में लपेटे जाने चाहिए, न कि कंपोज़िशन में निष्पादित किए जाने चाहिए।

तीसरी गलती BottomNavigation का उपयोग करते समय गलत बैक स्टैक प्रबंधन है। प्रत्येक टैब स्विच पर navigate() के माध्यम से सरल नेविगेशन मौजूदा में लौटने के बजाय स्टैक में एक नई एंट्री जोड़ता है। BottomNavigation के लिए, आपको restoreState = true और launchSingleTop = true के साथ navController.navigate() का उपयोग करना चाहिए, जो टैब स्विच करने पर स्थिति की सही बहाली सुनिश्चित करता है।

kotlin
fun NavController.navigateToTab(route: String) {
    navigate(route) {
        popUpTo(navController.graph.findStartDestination().id) {
            saveState = true
        }
        launchSingleTop = true
        restoreState = true
    }
}

अक्सर पूछे जाने वाले प्रश्न

composable() और सामान्य @Composable फ़ंक्शन में क्या अंतर है?

composable() एक एनोटेशन नहीं है, बल्कि NavHost का एक एक्सटेंशन फ़ंक्शन है जो एक रूट को UI से बांधता है। एक सामान्य @Composable फ़ंक्शन केवल लेआउट का वर्णन करता है, जबकि composable() उस लेआउट को एक निर्दिष्ट रूट के साथ नेविगेशन ग्राफ़ में रजिस्टर करता है, जिससे यह NavController के माध्यम से नेविगेशन के लिए सुलभ हो जाता है।

composable() स्क्रीन के बीच एक जटिल ऑब्जेक्ट कैसे पास करें?

पाथ पैरामीटर के माध्यम से केवल एक पहचानकर्ता (ID) पास करने की अनुशंसा की जाती है, और रिपॉजिटरी या ViewModel के माध्यम से ID द्वारा स्क्रीन पर ऑब्जेक्ट लोड करें। यदि आपको अभी भी ऑब्जेक्ट पास करने की आवश्यकता है, तो NavType.ParcelableType का उपयोग करें, लेकिन 1 KB से बड़े ऑब्जेक्ट पास करने से बचें — इससे TransactionTooLargeException हो सकता है।

स्क्रीन घुमाने पर composable() स्क्रीन पुनर्निर्मित क्यों होती है?

स्क्रीन घुमाने से कॉन्फ़िगरेशन परिवर्तन होता है, जो डिफ़ॉल्ट रूप से Activity को पुनर्निर्मित करता है। composable स्क्रीन की स्थिति को संरक्षित करने के लिए, सरल डेटा के लिए rememberSaveable या उस स्क्रीन के स्कोप के साथ ViewModel का उपयोग करें। Navigation Compose पुनर्निर्माण के बाद बैक स्टैक को पुनर्स्थापित करता है, लेकिन composable() फ़ंक्शन के अंदर की स्थिति rememberSaveable के बिना रीसेट हो जाती है।

क्या NavHost के बिना composable() का उपयोग किया जा सकता है?

नहीं, composable() NavGraphBuilder का एक एक्सटेंशन फ़ंक्शन है, जो केवल NavHost ब्लॉक के अंदर उपलब्ध है। नेविगेशन के बिना सरल UI प्रतिस्थापन के लिए, सशर्त रेंडरिंग (when, if) या AnimatedContent का उपयोग करें। composable() विशेष रूप से बैक स्टैक और डीप लिंक समर्थन के साथ रूटिंग के लिए डिज़ाइन किया गया है।

composable() में पहली नेविगेशन को वापसी नेविगेशन से कैसे अलग करें?

ViewModel के अंदर SavedStateHandle का उपयोग करें: पहली नेविगेशन पर, handle.get("initialized") null लौटाता है; वापसी नेविगेशन पर, यह सहेजा गया मान लौटाता है। वैकल्पिक रूप से, navController.previousBackStackEntry के माध्यम से बैक स्टैक में वर्तमान स्थिति का विश्लेषण करें — यदि यह null है, तो यह नेविगेशन स्टैक में पहली स्क्रीन है।

सारांश

  • composable() NavHost में स्क्रीन पंजीकरण फ़ंक्शन है, Jetpack Compose में नेविगेशन व्यवस्थित करने का मुख्य तरीका।
  • रूट — प्रत्येक स्क्रीन वैकल्पिक पाथ और क्वेरी पैरामीटर के साथ एक रूट स्ट्रिंग द्वारा पहचानी जाती है।
  • आर्गुमेंट — प्रिमिटिव, Parcelable और Serializable प्रकारों के समर्थन के साथ NavArgument के माध्यम से पास किए जाते हैं।
  • नेस्टिंग — composable() स्वतंत्र स्टैक के साथ मॉड्यूलर नेविगेशन व्यवस्थित करने के लिए नेस्टेड NavHost का समर्थन करता है।
  • प्रदर्शन — लेज़ी स्क्रीन इनिशियलाइज़ेशन मेमोरी बचाता है, स्क्रीन स्विचिंग गति 5–15 मि.से. है।
  • गलतियाँ — मुख्य समस्याएँ: NavController पुनर्निर्माण, composable बॉडी में navigate() के साथ अनंत पुनर्संयोजन, गलत BottomNavigation प्रबंधन।
  • माइग्रेशन — FragmentManager से composable() पर स्विच करने से नेविगेशन कोड की मात्रा 40–60% कम हो जाती है और Fragment जीवनचक्र से संबंधित बग की एक श्रेणी समाप्त हो जाती है।

हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे

IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।

परियोजना पर चर्चा करें

यह भी पढ़ें