viewModelScope: यह क्या है, ViewModel से जुड़ाव और Android में कार्य

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

viewModelScope androidx.lifecycle लाइब्रेरी से एक अंतर्निहित CoroutineScope है जो ViewModel के जीवनचक्र से जुड़ा होता है और इसके साफ़ होने पर स्वचालित रूप से रद्द हो जाता है। Google Android Developers, 2025 के अनुसार, viewModelScope MVVM आर्किटेक्चर में कोरूटीन लॉन्च करने का मानक तंत्र है, जो मेमोरी लीक के जोखिम के बिना सुरक्षित एसिंक्रोनस संचालन सुनिश्चित करता है। ViewModelScope डिफ़ॉल्ट रूप से Dispatchers.Main का उपयोग करता है, और इसके अंदर सभी IO संचालन withContext के माध्यम से निष्पादित होने चाहिए।

मुख्य बातें

  • viewModelScope — lifecycle-viewmodel-ktx से CoroutineScope, ViewModel.onCleared() पर रद्द होता है
  • Dispatchers.Main — डिफ़ॉल्ट डिस्पैचर, इसलिए कोरूटीन के अंदर UI अपडेट सुरक्षित हैं
  • onCleared — कॉलबैक जो viewModelScope में सभी सक्रिय कोरूटीन को स्वचालित रूप से रद्द करता है
  • clear() बनाम onCleared() — clear() को फ्रेमवर्क द्वारा onCleared से पहले बुलाया जाता है, जो scope रद्दीकरण सुनिश्चित करता है
  • launch — fire-and-forget संचालन के लिए viewModelScope में कोरूटीन शुरू करने का मुख्य तरीका

Android में viewModelScope क्या है?

viewModelScope ViewModel इंटरफ़ेस पर एक extension प्रॉपर्टी है, जिसे lifecycle-viewmodel-ktx लाइब्रेरी (संस्करण 2.1.0 से शुरू) में जोड़ा गया है। यह ViewModel जीवनचक्र से जुड़ा एक तैयार CoroutineScope प्रदान करता है।

kotlin
// Internal structure (simplified)
val ViewModel.viewModelScope: CoroutineScope
    get() {
        val scope = this.getTag(JOB_KEY)
        if (scope != null) return scope
        return CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
            .also { setTag(JOB_KEY, it) }
    }

Scope पहली बार एक्सेस करने पर लेज़ी (lazy) रूप से बनाया जाता है और setTag के माध्यम से कैश किया जाता है। यह SupervisorJob का उपयोग करता है, जिसका अर्थ है कि एक चाइल्ड कोरूटीन में अपवाद दूसरों को रद्द नहीं करता। डिफ़ॉल्ट डिस्पैचर Dispatchers.Main.immediate है, जो पहले से Main पर होने पर अतिरिक्त डिस्पैचिंग के बिना मुख्य थ्रेड पर कोड निष्पादित करता है।

viewModelScope को सफाई के बारे में कैसे सूचित किया जाता है

जब ViewModel जीवनचक्र छोड़ती है (Activity समाप्त होती है या Fragment हटा दिया जाता है), सिस्टम clear() को कॉल करता है, जो onCleared() को ट्रिगर करता है। इस कॉलबैक में, viewModelScope अपने Job को रद्द करता है, जो सभी सक्रिय कोरूटीन को पुनरावर्ती रूप से समाप्त करता है। तंत्र Closeable इंटरफ़ेस के माध्यम से कार्यान्वित किया गया है, जहाँ scope Job स्वचालित बंद करने के लिए एक संसाधन के रूप में पंजीकृत होता है।

viewModelScope कैसे काम करता है: ViewModel जीवनचक्र से जुड़ाव

viewModelScope का ViewModel जीवनचक्र से जुड़ाव तंत्र टैगिंग और onCleared कॉलबैक पर आधारित है। आइए इसे चरण दर चरण समझते हैं।

चरण 1: पहली बार एक्सेस पर scope निर्माण

जब ViewModel viewModelScope.launch { ... } निष्पादित करता है, getter जाँचता है कि JOB_KEY टैग के तहत पहले से कोई scope संग्रहीत है या नहीं। यदि scope मौजूद नहीं है, तो एक नया CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate) इंस्टेंस बनाया जाता है। Scope आंतरिक टैग मैप के माध्यम से ViewModel के अंदर संग्रहीत होता है।

चरण 2: कोरूटीन जीवनचक्र

viewModelScope.launch या viewModelScope.async के माध्यम से लॉन्च किए गए सभी कोरूटीन scope के SupervisorJob के चाइल्ड बन जाते हैं। वे मुख्य थ्रेड पर चलते हैं (जब तक withContext के माध्यम से कोई भिन्न डिस्पैचर निर्दिष्ट न किया गया हो)। जब तक ViewModel जीवित है, कोरूटीन सक्रिय, निलंबित या पूर्ण हो सकते हैं।

चरण 3: onCleared पर रद्दीकरण

जब सिस्टम ViewModel को नष्ट करता है, ViewModel.clear() कॉल किया जाता है। clear() के अंदर, निम्नलिखित होता है:

  • कस्टम सफाई तर्क के लिए onCleared() कॉल किया जाता है
  • addCloseable के माध्यम से पंजीकृत सभी Closeable संसाधन बंद किए जाते हैं
  • viewModelScope का Job Cancelled स्थिति में जाता है
  • सभी चाइल्ड कोरूटीन पुनरावर्ती रूप से रद्द किए जाते हैं
  • कचरा संग्रहण के लिए scope के संदर्भ मुक्त किए जाते हैं

रोटेशन सहनशीलता

जब स्क्रीन घुमाई जाती है, Activity पुनः बनाई जाती है, लेकिन ViewModel बनी रहती है (ViewModelStoreOwner के कारण)। इसका मतलब है कि viewModelScope सक्रिय रहता है और कोरूटीन बिना किसी रुकावट के निष्पादित होते रहते हैं। Activity के पुनः बनने के बाद, उसी ViewModel (और उसी scope) का पुनः उपयोग किया जाता है — डेटा लोडिंग शुरू से नहीं होती।

MVVM आर्किटेक्चर में viewModelScope

MVVM (Model-View-ViewModel) Android अनुप्रयोगों के लिए Google द्वारा अनुशंसित आर्किटेक्चर है। viewModelScope इसमें एसिंक्रोनस संचालन के निष्पादक के रूप में केंद्रीय स्थान रखता है।

आर्किटेक्चर परतों में viewModelScope की भूमिका

परतघटकviewModelScope की भूमिका
UIActivity / FragmentViewModel से StateFlow/LiveData का अवलोकन करता है
ViewModelViewModelviewModelScope के माध्यम से कोरूटीन लॉन्च करता है, UI स्थिति प्रबंधित करता है
RepositoryRepositoryviewModelScope कोरूटीन से कॉल की जाने वाली suspend फ़ंक्शन प्रदान करता है
DataDAO / Apiवास्तविक अनुरोध निष्पादित करता है (Room, Retrofit)

ViewModel viewModelScope के माध्यम से कोरूटीन लॉन्च करता है, जिसके अंदर यह Repository की suspend फ़ंक्शन को कॉल करता है। परिणाम StateFlow में रूपांतरित होता है, जिसे UI परत देखती है। यह डिज़ाइन जिम्मेदारियों का स्पष्ट विभाजन और प्रत्येक परत की स्वतंत्र परीक्षण क्षमता सुनिश्चित करता है।

ViewModel में viewModelScope क्यों, Fragment में क्यों नहीं

यदि कोरूटीन Fragment से लॉन्च किए जाते, तो स्क्रीन घुमाने पर Fragment के नष्ट होने के साथ वे रद्द हो जाते। ViewModel रोटेशन से बच जाती है, इसलिए इसके scope में लॉन्च किए गए कोरूटीन निष्पादित होते रहते हैं। डेटा लोड करते समय lifecycleScope की तुलना में viewModelScope का यह मुख्य लाभ है।

viewModelScope उपयोग उदाहरण

आइए Kotlin में Android अनुप्रयोग में viewModelScope के उपयोग के तीन व्यावहारिक परिदृश्य देखें।

उदाहरण 1: ViewModel निर्माण पर डेटा लोड करना

kotlin
class ProfileViewModel(
    private val repo: ProfileRepository
) : ViewModel() {

    private val _profile = MutableStateFlow<Profile?>(null)
    val profile: StateFlow<Profile?> = _profile

    init {
        loadProfile()
    }

    private fun loadProfile() {
        viewModelScope.launch {
            val result = repo.getProfile()
            _profile.value = result
        }
    }
}

init ब्लॉक में, प्रोफ़ाइल लोडिंग तुरंत शुरू होती है। कोरूटीन मुख्य थ्रेड पर (डिफ़ॉल्ट रूप से) चलता है। रिपॉज़िटरी अपने suspend फ़ंक्शन के अंदर नेटवर्क अनुरोध के लिए withContext(Dispatchers.IO) का उपयोग करता है, इसलिए ViewModel को थ्रेड स्विचिंग की चिंता नहीं करनी पड़ती।

उदाहरण 2: sealed class के माध्यम से त्रुटि प्रबंधन

kotlin
sealed class UiState {
    object Loading : UiState()
    data class Success(val data: List<Item>) : UiState()
    data class Error(val message: String) : UiState()
}
kotlin
fun fetchItems() {
    _state.value = UiState.Loading
    viewModelScope.launch {
        try {
            val items = repo.getItems()
            _state.value = UiState.Success(items)
        } catch (e: Exception) {
            _state.value = UiState.Error(e.message ?: "Unknown error")
        }
    }
}

UI स्थिति को sealed class UiState के माध्यम से वर्णित किया गया है। ViewModel प्रत्येक परिवर्तन पर स्थिति अपडेट करता है। Fragment StateFlow की सदस्यता लेता है और केवल वर्तमान स्थिति पर प्रतिक्रिया करता है, पिछले रोटेशन की पुरानी कॉल को अनदेखा करता है।

उदाहरण 3: नए अनुरोध पर पिछले कोरूटीन को रद्द करना

kotlin
private var searchJob: Job? = null

fun search(query: String) {
    searchJob?.cancel()
    searchJob = viewModelScope.launch {
        delay(300)
        val results = repo.search(query)
        _searchResults.value = results
    }
}

प्रत्येक नई खोज क्वेरी पर, पिछला कोरूटीन रद्द हो जाता है। delay(300) debounce लागू करता है — खोज केवल 300 मिलीसेकंड की निष्क्रियता के बाद निष्पादित होती है। यह सर्वर लोड को कम करता है और पुराने परिणामों को रोकता है।

viewModelScope बनाम lifecycleScope: कब क्या चुनें

दोनों scope AndroidX Lifecycle लाइब्रेरी द्वारा प्रदान किए गए हैं, लेकिन विभिन्न जीवनचक्रों से जुड़े हैं। चुनाव कार्य के प्रकार पर निर्भर करता है।

Scope तुलना

विशेषताviewModelScopelifecycleScope
स्वामीViewModelLifecycleOwner (Activity/Fragment)
रोटेशन पर रद्दनहीं (ViewModel बच जाती है)हाँ (Activity पुनः बनाई जाती है)
डिफ़ॉल्ट डिस्पैचरDispatchers.Main.immediateDispatchers.Main.immediate
उपलब्धViewModelActivity, Fragment, Service
सामान्य उपयोगडेटा लोडिंग, व्यावसायिक तर्कUI इंटरैक्शन, एनिमेशन

Google अनुशंसाएँ

Google सभी डेटा लोडिंग और प्रसंस्करण कार्यों के लिए viewModelScope का उपयोग करने की अनुशंसा करता है। lifecycleScope का उपयोग UI जीवनचक्र के किसी विशिष्ट क्षण से जुड़े संचालन के लिए किया जाना चाहिए — उदाहरण के लिए, पहली स्क्रीन उपस्थिति पर एनिमेशन शुरू करना या लोकेशन अपडेट की सदस्यता लेना जो स्क्रीन छोड़ने पर बंद हो जानी चाहिए।

viewModelScope के साथ सामान्य गलतियाँ

एक अच्छी तरह से प्रलेखित Android API में भी, डेवलपर्स विशिष्ट गलतियाँ करते हैं। आइए चार सबसे सामान्य समस्याओं को देखें।

गलती 1: scope रद्द होने के बाद UI अपडेट करना

सबसे खतरनाक गलती ViewModel के साफ़ होने के बाद StateFlow या LiveData को अपडेट करने का प्रयास करना है। हालाँकि viewModelScope onCleared() पर रद्द हो जाता है, एक कोरूटीन वास्तविक रद्दीकरण प्रभावी होने से पहले कोड निष्पादित कर सकता है। जाँच के लिए isActive का उपयोग करें या catch-ब्लॉक के पूरा होने पर भरोसा करें।

गलती 2: SupervisorJob पर विचार किए बिना कोरूटीन लॉन्च करना

viewModelScope आंतरिक रूप से SupervisorJob का उपयोग करता है, जो कोरूटीन के बीच त्रुटियों को अलग करता है। हालाँकि, यदि आप viewModelScope.launch के अंदर अपने स्वयं के Job() के साथ कोरूटीन लॉन्च करते हैं, तो वह कोरूटीन SupervisorJob का चाइल्ड बन जाता है लेकिन अन्य कोरूटीन में त्रुटियों के कारण रद्दीकरण से सुरक्षित नहीं रहेगा।

गलती 3: एक scope में बहुत अधिक कोरूटीन

हालाँकि viewModelScope की कोई सख्त सीमा नहीं है, हजारों सक्रिय कोरूटीन सिस्टम को धीमा कर सकते हैं। लंबी डेटा सूचियों के लिए, प्रत्येक आइटम के लिए अलग कोरूटीन बनाने के बजाय Flow का collectLatest के साथ उपयोग करें।

गलती 4: viewModelScope के बजाय GlobalScope का उपयोग करना

यदि viewModelScope के बजाय गलती से GlobalScope आयात किया जाता है, तो ViewModel के साफ़ होने पर कोरूटीन रद्द नहीं होगा। इससे मेमोरी लीक और संभावित क्रैश होते हैं। हमेशा सुनिश्चित करें कि कोरूटीन viewModelScope के माध्यम से लॉन्च किए गए हैं, विशेष रूप से Fragment उपवर्गों में।

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

क्या मैं viewModelScope का डिफ़ॉल्ट डिस्पैचर बदल सकता हूँ?

आप viewModelScope के डिस्पैचर को सीधे नहीं बदल सकते — यह Dispatchers.Main.immediate के रूप में हार्डकोड है। हालाँकि, कोरूटीन के अंदर आप withContext के माध्यम से दूसरे डिस्पैचर पर स्विच कर सकते हैं। परीक्षणों में डिस्पैचर बदलने के लिए, Rule के माध्यम से TestDispatcher का उपयोग करें।

मैं viewModelScope को Repository में कैसे पास करूँ?

scope को Repository में न पास करें — यह आर्किटेक्चर सिद्धांतों का उल्लंघन करता है। Repository को suspend फ़ंक्शन प्रदान करने चाहिए, और ViewModel स्वयं viewModelScope के माध्यम से कोरूटीन प्रबंधित करता है। यदि Repository को scope की आवश्यकता है, तो Clean Architecture के पक्ष में आर्किटेक्चर पर पुनर्विचार करें।

viewModelScope SupervisorJob का उपयोग क्यों करता है?

SupervisorJob सुनिश्चित करता है कि एक कोरूटीन में अपवाद (उदाहरण के लिए, कई स्वतंत्र अनुरोधों में से एक में लोडिंग त्रुटि) अन्य कोरूटीन को रद्द न करे। यह ViewModel परिदृश्य से मेल खाता है जहाँ विभिन्न स्क्रीन स्वतंत्र डेटा लोड करती हैं।

क्या Jetpack Compose में viewModelScope उपलब्ध है?

हाँ, viewModelScope किसी भी ViewModel में UI प्रकार (View System या Jetpack Compose) के बावजूद उपलब्ध है। Compose में, कोरूटीन भी viewModelScope के माध्यम से लॉन्च किए जाते हैं, जबकि UI प्रभावों के लिए LaunchedEffect और rememberCoroutineScope का उपयोग किया जाता है।

viewModelScope.cancel() कॉल करने पर कोरूटीन का क्या होता है?

viewModelScope.cancel() कॉल करने से scope तुरंत रद्द हो जाता है — सभी सक्रिय कोरूटीन CancellationException के साथ समाप्त हो जाते हैं। यदि उसके बाद viewModelScope.launch कॉल किया जाता है, तो getter के अगले एक्सेस पर स्वचालित रूप से एक नया scope बनाया जाता है।

सारांश

  • viewModelScope — ViewModel जीवनचक्र से जुड़ा CoroutineScope, onCleared() पर स्वचालित रूप से रद्द होता है
  • SupervisorJob + Dispatchers.Main — आंतरिक कॉन्फ़िगरेशन जो त्रुटि पृथक्करण और सुरक्षित UI एक्सेस सुनिश्चित करता है
  • स्क्रीन रोटेशन — ViewModel बच जाती है, इसलिए viewModelScope में कोरूटीन पुनरारंभ के बिना जारी रहते हैं
  • MVVM आर्किटेक्चर — viewModelScope ViewModel परत में एसिंक्रोनस संचालन के लिए केंद्रीय तत्व है
  • lifecycleScope — Activity/Fragment जीवनचक्र से जुड़े संचालन के लिए विकल्प, ViewModel के लिए नहीं
  • StateFlow — sealed class के माध्यम से viewModelScope कोरूटीन से UI तक डेटा पहुँचाने का पसंदीदा तरीका
  • GlobalScope खतरनाक है — viewModelScope को GlobalScope से बदलने से मेमोरी लीक और ऐप क्रैश होते हैं

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

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

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

यह भी पढ़ें