CoroutineScope एक Kotlin इंटरफ़ेस है जो कोरूटीन के जीवनचक्र को परिभाषित करता है और नए कोरूटीन चलाने के लिए संदर्भ प्रदान करता है। Kotlin दस्तावेज़ीकरण, 2025 के अनुसार, प्रत्येक CoroutineScope इंस्टेंस में CoroutineContext होता है और यह उसके अंदर चलाए गए सभी कोरूटीन को प्रबंधित करता है। जब scope रद्द (cancel) होता है, तो सभी चाइल्ड कोरूटीन स्वचालित रूप से रद्द हो जाते हैं, जिससे मेमोरी लीक रुकती है।
मुख्य बातें
CoroutineScope kotlinx.coroutines लाइब्रेरी का एक मूलभूत इंटरफ़ेस है जो कोरूटीन के लिए कंटेनर का काम करता है। यह कोरूटीन जीवनचक्र की सीमाएँ परिभाषित करता है: जब scope पूरा होता है, तो उसके अंदर के सभी कोरूटीन स्वचालित रूप से रद्द हो जाते हैं।
public interface CoroutineScope {
public val coroutineContext: CoroutineContext
}
इंटरफ़ेस में सिर्फ एक फ़ील्ड है — coroutineContext। इसके माध्यम से, scope उसके अंदर चलाए गए सभी कोरूटीन के लिए डिस्पैचर (Dispatcher), जॉब (Job), अपवाद हैंडलर और अन्य संदर्भ तत्व प्रदान करता है।
कोरूटीन चलाने वाले सभी फ़ंक्शन — launch, async, runBlocking — CoroutineScope पर एक्सटेंशन फ़ंक्शन हैं। इसका मतलब है कि इन्हें केवल scope ऑब्जेक्ट उपलब्ध होने पर ही कॉल किया जा सकता है। यह डिज़ाइन सुनिश्चित करता है कि प्रत्येक कोरूटीन का एक स्पष्ट रूप से परिभाषित पैरेंट और जीवनचक्र हो।
Android में, प्रत्येक आर्किटेक्चरल कंपोनेंट का अपना scope होता है: ViewModel के लिए viewModelScope, Activity/Fragment के लिए lifecycleScope। सर्वर ऐप्लिकेशन में, scope को HTTP अनुरोध या डेटाबेस कनेक्शन पूल से बाँधा जा सकता है।
CoroutineScope की आंतरिक कार्यप्रणाली को समझने के लिए Job की अवधारणा और संरचनात्मक समवर्तीता के सिद्धांत से परिचित होना आवश्यक है।
प्रत्येक कोरूटीन चलने पर एक Job ऑब्जेक्ट (या async के लिए Deferred) लौटाता है। Job एक सीमित जीवनचक्र वाले कार्य का प्रतिनिधित्व करता है: New, Active, Completing, Completed, Cancelling, Cancelled। Job ऑब्जेक्ट एक पेड़ संरचना बनाते हैं:
संरचनात्मक समवर्तीता Kotlin Coroutines का एक प्रमुख आर्किटेक्चरल सिद्धांत है, जिसमें कोरूटीन का जीवनचक्र उसके scope के जीवनचक्र से बंधा होता है। यह “फायर-एंड-फ़ॉरगेट” मॉडल के विपरीत है, जहाँ कोरूटीन scope के पूरा होने के बाद भी जीवित रहता है। संरचनात्मक समवर्तीता के लाभ:
जब scope.cancel() कॉल किया जाता है, तो scope का Job Cancelled स्थिति में चला जाता है, जो सभी चाइल्ड Job को पुनरावर्ती रूप से रद्द करता है। रद्दीकरण के बाद, scope का पुन: उपयोग केवल नया CoroutineScope इंस्टेंस बनाकर ही किया जा सकता है।
आप CoroutineScope को फ़ैक्टरी फ़ंक्शन के माध्यम से या अपनी क्लास में इंटरफ़ेस लागू करके बना सकते हैं। दोनों तरीकों को देखते हैं।
val scope = CoroutineScope(Dispatchers.Default + SupervisorJob())
scope.launch {
println("Running on ${Thread.currentThread().name}")
}
फ़ैक्टरी फ़ंक्शन CoroutineContext लेता है और निर्दिष्ट संदर्भ के साथ scope बनाता है। उदाहरण CPU-गहन कार्यों के लिए Dispatchers.Default और SupervisorJob का उपयोग करता है, जो चाइल्ड कोरूटीन के बीच अपवादों को अलग करता है।
class MyRepository {
private val scope = CoroutineScope(Dispatchers.IO + Job())
suspend fun fetchData(): Data = scope.async {
api.getData()
}.await()
fun cleanup() {
scope.cancel()
}
}
हम scope को क्लास फ़ील्ड के रूप में संग्रहीत करते हैं और इसे रद्द करने के लिए मैन्युअल रूप से cleanup कॉल करते हैं। यह दृष्टिकोण प्रबंधित जीवनचक्र वाले कंपोनेंट — जैसे रिपॉजिटरी या मैनेजर — के लिए उपयुक्त है।
Kotlin by कीवर्ड के माध्यम से CoroutineScope कार्यान्वयन को डेलिगेट करने की अनुमति देता है:
class DataLoader : CoroutineScope by CoroutineScope(Dispatchers.IO) {
fun load() {
launch {
// coroutine runs in DataLoader scope
}
}
}
यह दृष्टिकोण तब सुविधाजनक है जब क्लास स्वयं एक scope है और कोरूटीन चलाने के तरीके प्रदान करना चाहती है। लेकिन सावधान रहें: क्लास CoroutineScope के सभी तरीकों को इनहेरिट करती है, जिसमें cancel भी शामिल है, जो एनकैप्सुलेशन को तोड़ सकता है।
GlobalScope पूरे ऐप्लिकेशन के लिए एक सिंगलटन CoroutineScope है। प्रोडक्शन कोड में इसका उपयोग आधिकारिक रूप से अनुशंसित नहीं है।
JetBrains GlobalScope को केवल दुर्लभ परिदृश्यों में अनुमति देता है: एप्लिकेशन-स्तरीय पृष्ठभूमि प्रक्रियाएँ जो सभी Activities बंद होने के बाद भी चलनी चाहिए (जैसे डेटा सिंक्रोनाइज़ेशन, एनालिटिक्स)। लेकिन इन मामलों में भी, CoroutineScope(SupervisorJob()) के साथ अपना खुद का scope बनाना बेहतर है।
हमेशा कस्टम CoroutineScope का उपयोग करें जिसमें स्पष्ट जीवनचक्र प्रबंधन हो। Android में, ये viewModelScope और lifecycleScope हैं। सर्वर ऐप्लिकेशन में, प्रत्येक अनुरोध या कनेक्शन पूल के लिए scope बनाएँ।
दोनों फ़ंक्शन सस्पेंड फ़ंक्शन हैं जो समानांतर कार्यों के लिए अस्थायी scope बनाते हैं, लेकिन अपवादों के साथ उनका व्यवहार मौलिक रूप से भिन्न होता है।
| विशेषता | coroutineScope | supervisorScope |
|---|---|---|
| त्रुटि पर व्यवहार | चाइल्ड कोरूटीन में अपवाद बाकी सभी को रद्द करता है | चाइल्ड कोरूटीन में अपवाद बाकी को नहीं रद्द करता |
| त्रुटि प्रसार | हाँ, पहला अपवाद बाहर फैलता है | हाँ, पहला अपवाद बाहर फैलता है |
| डिफ़ॉल्ट Job | Job() — चाइल्ड पैरेंट से बंधे हैं | SupervisorJob() — चाइल्ड एक-दूसरे पर निर्भर नहीं |
| विशिष्ट उपयोग-मामला | एकाधिक चरणों का परमाणु संचालन | स्वतंत्र समानांतर कार्य (UI लोड) |
coroutineScope का उपयोग करें जब कई समानांतर संचालन एक एकल परमाणु संचालन बनाते हैं। उदाहरण के लिए, तीन सर्वरों से डेटा लोड करना: यदि एक अनुरोध विफल होता है, तो बाकी अर्थहीन हैं।
suspend fun loadProductPage(): ProductPage = coroutineScope {
val product = async { api.getProduct() }
val reviews = async { api.getReviews() }
ProductPage(product.await(), reviews.await())
}
यदि getProduct या getReviews अपवाद फेंकता है — दोनों कोरूटीन रद्द हो जाते हैं, और अपवाद कॉल करने वाले कोड में फैल जाता है।
supervisorScope का उपयोग करें जब समानांतर संचालन एक-दूसरे पर निर्भर न हों। उदाहरण के लिए, कई स्वतंत्र अनुभागों में प्रोफ़ाइल डेटा लोड करना: यदि अनुशंसा अनुभाग विफल होता है, तो प्रोफ़ाइल शीर्षक और मित्र सूची प्रदर्शित होनी चाहिए।
Kotlin में CoroutineScope का उपयोग करते समय डेवलपर्स की सबसे सामान्य गलतियों पर नज़र डालते हैं।
कोरूटीन लीक का सबसे सामान्य परिदृश्य कंपोनेंट समाप्त होने पर cancel कॉल किए बिना scope बनाना है। यदि scope रद्द नहीं किया गया, तो कोरूटीन चलते रहते हैं, ऑब्जेक्ट्स के संदर्भ रखते हैं। Android में, viewModelScope या lifecycleScope का उपयोग करें, जो स्वचालित रूप से रद्द हो जाते हैं।
GlobalScope Android कंपोनेंट जीवनचक्र को अनदेखा करता है। Activity बंद होने के बाद GlobalScope में चलाया गया कोरूटीन निष्पादित होता रहेगा और UI अपडेट करने का प्रयास करेगा — जिससे क्रैश होगा। UI कंपोनेंट के लिए हमेशा lifecycleScope का उपयोग करें।
cancel() कॉल करने के बाद, scope का पुन: उपयोग नहीं किया जा सकता — उसके अंदर के सभी कोरूटीन पहले ही पूरे हो चुके हैं। फ़ैक्टरी फ़ंक्शन के माध्यम से नया CoroutineScope इंस्टेंस बनाएँ। Job() पुन: सक्रियण का समर्थन नहीं करता।
by के साथ डेलिगेट करने पर, क्लास को सार्वजनिक cancel() विधि मिलती है जिसे कहीं से भी कॉल किया जा सकता है, जिससे एनकैप्सुलेशन टूटता है। इंटरफ़ेस डेलिगेट करने के बजाय scope को प्राइवेट फ़ील्ड के रूप में संग्रहीत करें।
अक्सर पूछे जाने वाले प्रश्न
CoroutineScope एक इंटरफ़ेस है जो CoroutineContext का मालिक है और कोरूटीन जीवनचक्र के लिए जिम्मेदार है। CoroutineContext तत्वों (डिस्पैचर, job, त्रुटि हैंडलर) का एक सेट है जो परिभाषित करता है कि कोरूटीन “कैसे” निष्पादित होता है। एक अंतर: scope कोरूटीन बनाता है, जबकि संदर्भ उनके व्यवहार को नियंत्रित करता है।
हाँ, यह एक मानक पैटर्न है: CoroutineScope(Dispatchers.IO + SupervisorJob()). SupervisorJob किसी एक चाइल्ड कोरूटीन में अपवाद होने पर बाकी कोरूटीन के कैस्केडिंग रद्दीकरण को रोकता है। यह स्वतंत्र समानांतर कार्यों के लिए उपयोगी है जहाँ एक में त्रुटि दूसरे को नहीं रोकनी चाहिए।
scope में कोरूटीन की कोई सीमा नहीं है — वे केवल उपलब्ध मेमोरी और डिस्पैचर सेटिंग्स द्वारा सीमित हैं। व्यावहारिक सीमा आमतौर पर एक scope में हजारों सक्रिय कोरूटीन होती है। हालाँकि, बड़ी संख्या में कोरूटीन आर्किटेक्चरल समस्याओं का संकेत हो सकती है।
सही तरीका है कंस्ट्रक्टर के माध्यम से क्लास में scope पास करना या kotlinx-coroutines-test से runBlockingTest / runTest का उपयोग करना। परीक्षणों में, आप scope को TestCoroutineDispatcher से बदल सकते हैं और कोरूटीन निष्पादन को मैन्युअल रूप से नियंत्रित कर सकते हैं।
नहीं, scope कोरूटीन के लिए एक बाहरी कंटेनर है। कोरूटीन स्वयं scope नहीं है। हालाँकि, कोरूटीन के अंदर आप coroutineScope या supervisorScope के माध्यम से चाइल्ड कोरूटीन को समानांतर चलाने के लिए नया scope बना सकते हैं।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें