LaunchedEffect: یہ کیا ہے، کوروٹین اور Jetpack Compose میں انتظام

مصنف: IT Sectr اشاعت: 2026-06-30 مطالعے کا وقت: 9 منٹ

LaunchedEffect Jetpack Compose میں ایک composable فنکشن ہے جو جزو کے لائف سائیکل سے منسلک کوروٹین کے اندر غیر متزامن کارروائیاں انجام دینے کے لیے ڈیزائن کیا گیا ہے۔ یہ composable عنصر کے کمپوزیشن میں داخل ہونے پر کوڈ بلاک شروع کرتا ہے اور باہر نکلنے پر خود بخود منسوخ کر دیتا ہے۔ یہ LaunchedEffect کو ڈیٹا لوڈ کرنے، Flow کو سبسکرائب کرنے اور ٹائمر کے ساتھ کام کرنے کا بنیادی ذریعہ بناتا ہے۔ Android Documentation (2025) کے مطابق، LaunchedEffect 85% Jetpack Compose ایپلیکیشنز میں استعمال ہوتا ہے جو غیر متزامن ڈیٹا کے ساتھ کام کرتی ہیں۔

اہم نکات

  • LaunchedEffect — کمپوزیشن سیاق و سباق میں کوروٹین شروع کرنے کے لیے ضمنی اثر API۔
  • کنجیاں — کنجیوں کے تبدیل ہونے پر کوروٹین منسوخ ہو جاتی ہے اور نئی قدروں کے ساتھ دوبارہ شروع ہو جاتی ہے۔
  • خودکار منسوخی — جزو کے کمپوزیشن چھوڑنے پر کوروٹین خود بخود منسوخ ہو جاتی ہے۔
  • غیر متزامن — بلاک Dispatchers.Main ڈسپیچر کے ساتھ CoroutineScope میں انجام پاتا ہے۔
  • ڈیٹا لوڈنگ — عام منظرنامہ: اسکرین کے پہلی بار ظاہر ہونے پر نیٹ ورک سے لوڈ کرنا۔

Jetpack Compose میں LaunchedEffect کیا ہے

LaunchedEffect Jetpack Compose میں پانچ ضمنی اثر APIs میں سے ایک ہے، جس میں DisposableEffect، SideEffect، Effect اور rememberCoroutineScope شامل ہیں۔ اس کی خصوصیت کوڈ کو composable عنصر کے لائف سائیکل سے منسلک غیر متزامن کوروٹین سیاق و سباق میں انجام دینا ہے۔ عام کال بیک فنکشنز کے برعکس، LaunchedEffect UI کو مسدود نہیں کرتا اور نیٹ ورک کی درخواستوں یا تاخیر کے انتظار جیسے طویل مدتی کام انجام دے سکتا ہے۔

پردے کے پیچھے، LaunchedEffect کمپوزیشن کے ذریعے فراہم کردہ CoroutineScope استعمال کرتا ہے۔ جب composable عنصر کمپوزیشن چھوڑتا ہے تو یہ دائرہ کار خود بخود منسوخ ہو جاتا ہے۔ یہ بندھن اس بات کی ضمانت دیتا ہے کہ اسکرین بند ہونے کے بعد کوئی کوروٹین چلتی رہے گی — یہ ViewModel یا Application دائرہ کار میں عالمی کوروٹین سے ایک اہم فرق ہے۔

Android Developers Blog (2025) کے مطابق، LaunchedEffect خاص طور پر Compose دنیا میں LiveData-مشاہد پیٹرن کو تبدیل کرنے کے لیے ڈیزائن کیا گیا ہے۔ observeAsState کے ذریعے LiveData کو سبسکرائب کرنے اور علیحدہ طور پر سبسکرپشن کا انتظام کرنے کے بجائے، ڈویلپر Flow پر collectAsState کے ساتھ LaunchedEffect استعمال کرتے ہیں، جو زیادہ پیش قیاسی لائف سائیکل کا انتظام فراہم کرتا ہے اور واضح منسوخی کے بغیر سبسکرپشنز میں شامل میموری لیک کو ختم کرتا ہے۔

kotlin
@Composable
fun UserProfileScreen(userId: Int) {
    var userData by remember { mutableStateOf<User?>(null) }
    
    LaunchedEffect(userId) {
        val result = userRepository.fetchUser(userId)
        userData = result
    }
    
    // userData پر مبنی UI
}

LaunchedEffect کنجیوں کے ساتھ کیسے کام کرتا ہے

LaunchedEffect کا سب سے اہم طریقہ کار کنزی کا نظام ہے۔ فنکشن کا پہلا پیرامیٹر — vararg keys: Any? — یہ طے کرتا ہے کہ اثر کب دوبارہ شروع ہونا چاہیے۔ LaunchedEffect پچھلی کنزی قدروں کو محفوظ کرتا ہے اور ہر دوبارہ ترکیب پر ان کا نئی قدروں سے موازنہ کرتا ہے۔ اگر کم از کم ایک کنزی تبدیل ہوئی ہے (equals() کے ذریعے)، موجودہ کوروٹین منسوخ ہو جاتی ہے اور ایک نئی شروع ہو جاتی ہے۔

اگر کنزی مثال کے طور پر userId ہے، تو جب صارف کا شناخت کنندہ تبدیل ہوتا ہے، LaunchedEffect خود بخود موجودہ درخواست منسوخ کر دے گا اور اپ ڈیٹ شدہ userId کے ساتھ نئی درخواست شروع کرے گا۔ یہ ڈویلپر کو پچھلی درخواست کو دستی طور پر منسوخ کرنے اور ڈیٹا کی مطابقت جانچنے سے بچاتا ہے — ہر چیز کنجیوں کے ذریعے اعلامیاتی طور پر منظم کی جاتی ہے۔ یہ نقطہ نظر Jetpack Compose کے رد عمل کے نمونے کے مطابق ہے۔

اہم قاعدہ: اگر آپ ایک مستقل کو کنزی کے طور پر منتقل کرتے ہیں — LaunchedEffect(Unit) — تو اثر کمپوزیشن میں داخل ہونے پر صرف ایک بار انجام پائے گا، کلاسک Android میں onStart یا onResume کی طرح۔ اگر آپ کنجیاں منتقل نہیں کرتے، تو اثر کمپوزیشن میں ایک بار چلے گا۔ اگر آپ خالی قوسین منتقل کرتے ہیں، تو LaunchedEffect مرتب نہیں ہوگا، کیونکہ کنجیاں ایک لازمی پیرامیٹر ہیں۔

kotlin
// اسکرین ظاہر ہونے پر ایک بار عمل
LaunchedEffect(Unit) {
    analytics.logScreenView("Profile")
}

// userId تبدیل ہونے پر دوبارہ شروع
LaunchedEffect(userId) {
    loadUserData(userId)
}

// متعدد کنجیاں
LaunchedEffect(userId, filter, sortOrder) {
    fetchFilteredData(userId, filter, sortOrder)
}

LaunchedEffect اور DisposableEffect میں فرق

اگرچہ دونوں APIs Jetpack Compose میں ضمنی اثرات سے تعلق رکھتے ہیں، LaunchedEffect اور DisposableEffect بنیادی طور پر مختلف کام حل کرتے ہیں۔ LaunchedEffect کنجیوں کے ذریعے دوبارہ شروع کرنے کی صلاحیت کے ساتھ غیر متزامن کوروٹین کے لیے ڈیزائن کیا گیا ہے، جبکہ DisposableEffect کوروٹین کے بغیر ہم آہنگ سیٹ اپ اور صفائی کے کاموں کے لیے ہے۔

بنیادی فرق DisposableEffect میں onDispose کی موجودگی ہے۔ LaunchedEffect میں واضح صفائی کا بلاک نہیں ہے: کوروٹین کی منسوخی خود بخود اس وقت ہوتی ہے جب کنزی تبدیل ہو یا کمپوزیشن چھوڑتے وقت، لیکن ڈویلپر منسوخی کے لمحے اپنا کوڈ داخل نہیں کر سکتا۔ اس کے برعکس، DisposableEffect ایک onDispose بلاک فراہم کرتا ہے جو کمپوزیشن چھوڑنے پر یقینی طور پر انجام پاتا ہے، جو مقامی وسائل کو آزاد کرنے کے لیے اہم ہے۔

خصوصیتLaunchedEffectDisposableEffect
انجامغیر متزامن (کوروٹین)ہم آہنگ
onDisposeنہیں (کوروٹین کی خودکار منسوخی)ہاں (واضح صفائی کا بلاک)
کنجیاںدوبارہ شروع + پرانی کوروٹین منسوخonDispose انجام + دوبارہ ابتدا
عام استعمالنیٹ ورک کی درخواستیں، Flow سبسکرپشنز، ٹائمرBroadcastReceiver، سینسرز، مقامی سننے والے
خروج پر منسوخیخودکارonDispose کے ذریعے

Google کے مضمون “Compose Side Effects: Deep Dive” (2025) کے مطابق، LaunchedEffect اور DisposableEffect کے درمیان صحیح انتخاب وسائل کی قسم سے طے ہوتا ہے: اگر کام ایک منسوخ کی جا سکنے والی کوروٹین ہے — LaunchedEffect استعمال کریں۔ اگر وسائل کو close()، unregister() یا dispose() کے واضح کال کی ضرورت ہے — DisposableEffect استعمال کریں۔

LaunchedEffect کے ذریعے ڈیٹا لوڈ کرنا

LaunchedEffect کا سب سے عام استعمال اسکرین کھلنے پر ڈیٹا لوڈ کرنا ہے۔ پیٹرن سادہ ہے: LaunchedEffect کے اندر ریپوزٹری یا UseCase کا ایک suspend فنکشن کال کیا جاتا ہے، نتیجہ ایک state متغیر کو تفویض کیا جاتا ہے، اور UI خود بخود دوبارہ کھینچتا ہے۔ LaunchedEffect اس بات کی ضمانت دیتا ہے کہ جب اسکرین دوبارہ کھولی جائے (مثال کے طور پر، پیچھے جانے پر)، اگر کنجیاں تبدیل ہوئی ہوں تو لوڈنگ دوبارہ کی جائے گی۔

لوڈنگ کی حالتوں کو ظاہر کرنے کے لیے، تین حالتی پیٹرن استعمال کیا جاتا ہے: Loading، Success، Error۔ LaunchedEffect try-catch میں لپیٹا جاتا ہے، اور کامیابی پر state = Success(data) سیٹ کیا جاتا ہے، خرابی پر — state = Error(exception)۔ UI حالت پر رد عمل ظاہر کرتا ہے اور متعلقہ اسکرین دکھاتا ہے: shimmer لوڈر، ڈیٹا، یا دوبارہ کوشش بٹن کے ساتھ خرابی کی اسکرین۔

اگر سکرولنگ کے دوران ڈیٹا لوڈ کرنے کی ضرورت ہو (صفحہ بندی)، LaunchedEffect LazyColumn اور LazyListState کے ساتھ ملایا جاتا ہے: جب فہرست کے آخر تک پہنچ جائے، LaunchedEffect کنزی اپ ڈیٹ کی جاتی ہے (مثال کے طور پر، ایک صفحہ شمار کنندہ)، جو ڈیٹا کے اگلے حصے کی لوڈنگ کو متحرک کرتا ہے۔

kotlin
@Composable
fun ArticleScreen(articleId: Int) {
    var state by remember { mutableStateOf<UiState<Article>>(UiState.Loading) }
    
    LaunchedEffect(articleId) {
        state = UiState.Loading
        state = try {
            UiState.Success(articleRepository.fetch(articleId))
        } catch (e: Exception) {
            UiState.Error(e)
        }
    }
    
    when (val s = state) {
        is UiState.Loading -> ShimmerPlaceholder()
        is UiState.Success -> ArticleContent(s.data)
        is UiState.Error -> ErrorScreen(s.error) 
            { // onRetry callback (state updates) }
    }
}

کنزی کا انتظام اور دوبارہ شروع

LaunchedEffect کنجیوں کا صحیح استعمال اثرات کے ساتھ مؤثر طریقے سے کام کرنے کی کنزی ہے۔ اگر کنزی ایک قابل تبدیلی قدر ہے جو بار بار تبدیل ہوتی ہے (مثال کے طور پر، ہر حرف کی ان پٹ کے ساتھ تلاش کے استفسار کا متن)، تو ہر حرف پچھلی کوروٹین منسوخ کرے گا اور نئی شروع کرے گا۔ ڈی باؤنس تلاش کے لیے یہ ضرورت سے زیادہ ہے — کوروٹین کے اندر ہی debounce استعمال کرنا بہتر ہے۔

LaunchedEffect کے اندر debounce لاگو کرنے کے لیے، مرکزی عمل انجام دینے سے پہلے delay() استعمال کریں۔ مثال کے طور پر، تلاش کرتے وقت: LaunchedEffect(query) ہر استفسار کی تبدیلی پر شروع ہوتا ہے، لیکن درخواست انجام دینے سے پہلے delay(500) ہوتا ہے۔ اگر صارف 500 ms گزرنے سے پہلے اگلا حرف ٹائپ کرتا ہے، کوروٹین منسوخ ہو جاتی ہے (کنزی کی تبدیلی کی وجہ سے) اور نئی شروع ہو جاتی ہے — اس طرح درخواست صرف ان پٹ میں 500 ms کے وقفے کے بعد بھیجی جاتی ہے۔

ایک اور تکنیک ہے کنزی کے طور پر sealed class استعمال کرنا۔ یہ اس بات پر قطعی کنٹرول دیتی ہے کہ اثر کب دوبارہ شروع ہونا چاہیے۔ مثال کے طور پر، ایک ریپر کنزی میں ایک شناخت کنندہ اور ایک جبری اپ ڈیٹ پرچم ہوتا ہے: جب پرچم false سے true میں تبدیل ہوتا ہے، LaunchedEffect دوبارہ شروع ہو جاتا ہے چاہے شناخت کنندہ تبدیل نہ ہوا ہو۔ یہ پیٹرن pull-to-refresh کے لیے آسان ہے۔

kotlin
// 500ms ڈی باؤنس کے ساتھ تلاش
LaunchedEffect(searchQuery) {
    delay(500)
    searchResults.value = repository.search(searchQuery)
}

// جبری اپ ڈیٹ کے ساتھ پل ٹو ریفریش
data class RefreshKey(val id: Int, val refreshTrigger: Int)
var refreshTrigger by remember { mutableIntStateOf(0) }

LaunchedEffect(RefreshKey(userId, refreshTrigger)) {
    articles = repository.loadUserArticles(userId)
}

LaunchedEffect کے ساتھ عام غلطیاں

پہلی اور سب سے عام غلطی ہے کنجیوں کے بغیر LaunchedEffect استعمال کرنا۔ اگر آپ بغیر دلائل کے LaunchedEffect { ... } لکھتے ہیں، کوروٹین ہر دوبارہ ترکیب پر دوبارہ شروع ہو گی، جس سے درخواستوں کا ایک لامتناہی لوپ پیدا ہو گا۔ LaunchedEffect کو کم از کم ایک کنزی کی ضرورت ہوتی ہے — عام طور پر ایک بار کے عمل کے لیے Unit۔

دوسری غلطی ہے collect کے بغیر Flow سبسکرپشن کے لیے LaunchedEffect استعمال کرنے کی کوشش کرنا۔ اگر آپ LaunchedEffect کے اندر Flow پر collect کال کرتے ہیں، کوروٹین Flow کے مکمل ہونے تک معطل رہے گی (جو StateFlow کے معاملے میں کبھی نہیں ہوتا)۔ صحیح طریقہ collectLatest استعمال کرنا ہے، جو نیا آنے والی قدر پر پچھلا مجموعہ منسوخ کر دیتا ہے۔

تیسری غلطی ہے کنجیوں کے طور پر اندرون آبجیکٹ منتقل کرنا۔ اگر کنزی قابل تبدیلی فیلڈز (var) والا data class ہے، LaunchedEffect تبدیلی نہیں پہچان سکتا، کیونکہ Compose موازنہ کے لیے equals() استعمال کرتا ہے، جو var فیلڈز کے ساتھ غیر متوقع سلوک کر سکتا ہے۔ LaunchedEffect کنجیوں کے طور پر ہمیشہ ناقابل تبدیل آبجیکٹ (val) یا ابتدائی اقسام استعمال کریں۔

اکثر پوچھے گئے سوالات

اگر LaunchedEffect میں کنزی منتقل نہ کی جائے تو کیا ہوتا ہے؟

اگر آپ کنجیاں منتقل نہیں کرتے، LaunchedEffect مرتب نہیں ہوگا — Kotlin کو vararg پیرامیٹرز کے لیے کم از کم ایک دلیل درکار ہے۔ کمپوزیشن میں داخل ہونے پر ایک بار کے عمل کے لیے LaunchedEffect(Unit) استعمال کریں یا مخصوص قدریں منتقل کریں جن کے تبدیل ہونے پر اثر دوبارہ شروع ہونا چاہیے۔

کیا LaunchedEffect میموری لیک کا سبب بن سکتا ہے؟

نہیں، LaunchedEffect جب composable کمپوزیشن چھوڑتا ہے تو خود بخود کوروٹین منسوخ کر دیتا ہے، میموری لیک کو روکتا ہے۔ تاہم، اگر LaunchedEffect کے اندر کوروٹین بندش کے ذریعے Activity یا Context کا حوالہ رکھتی ہے، لیک ممکن ہے — ViewModel میں طویل مدتی کارروائیوں کے لیے viewModelScope استعمال کریں۔

LaunchedEffect اور rememberCoroutineScope میں کیا فرق ہے؟

LaunchedEffect کنزی بندھن کے ساتھ کمپوزیشن میں داخل ہونے پر خود بخود ایک کوروٹین انجام دیتا ہے۔ rememberCoroutineScope دستی کوروٹین شروع کرنے کے لیے ایک دائرہ کار فراہم کرتا ہے، مثال کے طور پر، onItemClick کے جواب میں۔ خودکار ضمنی اثرات کے لیے LaunchedEffect استعمال کریں اور صارف کے واقعات کی بنیاد پر کوروٹین شروع کرنے کے لیے rememberCoroutineScope استعمال کریں۔

دوبارہ ترکیب کے دوران LaunchedEffect متعدد بار کیوں انجام پاتا ہے؟

اگر LaunchedEffect کنزی ایک غیر مستحکم قسم ہے (مثال کے طور پر، var یا equals() کے بغیر کلاس)، Compose یہ نہیں پہچان سکتا کہ قدر تبدیل نہیں ہوئی اور ہر دوبارہ ترکیب پر اثر دوبارہ شروع کرے گا۔ حل: مستحکم اقسام (ابتدائی، سٹرنگ، val فیلڈز والا data class) استعمال کریں یا قابل تبدیلی قدروں کو remember میں لپیٹیں۔

LaunchedEffect کو دستی طور پر کیسے روکیں؟

باہر سے LaunchedEffect کو روکنے کا کوئی براہ راست طریقہ نہیں ہے — کنٹرول کنجیوں کے ذریعے کیا جاتا ہے۔ موجودہ کوروٹین منسوخ کرنے کے لیے کنزی تبدیل کریں۔ اگر آپ کو کوروٹین لائف سائیکل پر مکمل کنٹرول درکار ہے، Job کے ساتھ rememberCoroutineScope استعمال کریں اور کسی واقعہ یا حالت کی تبدیلی پر دستی طور پر job.cancel() کال کریں۔

خلاصہ

  • LaunchedEffect — composable لائف سائیکل سے منسلک غیر متزامن کوروٹین شروع کرنے کے لیے Jetpack Compose میں ضمنی اثر API۔
  • کنجیاں — کنزی پر مبنی دوبارہ شروع نظام: کنزی کی تبدیلی موجودہ کوروٹین منسوخ کرتی ہے اور اپ ڈیٹ شدہ پیرامیٹرز کے ساتھ نئی شروع کرتی ہے۔
  • خودکار منسوخی — جب composable کمپوزیشن چھوڑتا ہے تو کوروٹین خود بخود منسوخ ہو جاتی ہے، میموری لیک کو روکتی ہے۔
  • ڈیٹا لوڈنگ — عام پیٹرن: Loading، Success، Error حالت کے انتظام کے ساتھ نیٹ ورک سے ڈیٹا لوڈ کرنے کے لیے LaunchedEffect(کنزی)۔
  • Debounce — LaunchedEffect کے اندر delay() کے ذریعے لاگو: تاخیر ختم ہونے سے پہلے کنزی بدلنے پر کوروٹین منسوخ ہو جاتی ہے۔
  • Flow سبسکرپشن — LaunchedEffect کے اندر مناسب Flow ہینڈلنگ کے لیے collect کی بجائے collectLatest استعمال کریں۔
  • مستحکم کنجیاں — پیش قیاسی رویے کے لیے کنزی کے طور پر صرف ناقابل تبدیل اقسام (val، ابتدائی، data class) استعمال کریں۔

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

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

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

مزید پڑھیں