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) ڈیباؤنس کو نافذ کرتا ہے — تلاش صرف 300 ms کی غیرفعالیت کے بعد انجام دی جاتی ہے۔ یہ سرور کے بوجھ کو کم کرتا ہے اور پرانے نتائج کو روکتا ہے۔

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 استعمال کریں یا کیچ بلاک کی تکمیل پر بھروسہ کریں۔

غلطی 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 منظرنامے سے مطابقت رکھتا ہے جہاں مختلف اسکرینیں آزاد ڈیٹا لوڈ کرتی ہیں۔

کیا viewModelScope Jetpack Compose میں دستیاب ہے؟

ہاں، viewModelScope UI کی قسم (View System یا Jetpack Compose) سے قطع نظر کسی بھی ViewModel میں دستیاب ہے۔ 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 — ViewModel کے بجائے Activity/Fragment لائف سائیکل سے منسلک کارروائیوں کے لیے متبادل
  • StateFlow — sealed class کے ذریعے viewModelScope کوروٹین سے UI تک ڈیٹا منتقل کرنے کا ترجیحی طریقہ
  • GlobalScope خطرناک ہے — viewModelScope کو GlobalScope سے تبدیل کرنے سے میموری لیک اور ایپ کریش ہوتے ہیں

ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے

IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔

پروجیکٹ پر بحث کریں

مزید پڑھیں