LiveData: یہ کیا ہے، Android Architecture کا جزو

مصنف: IT Sectr اشاعت: 2026-02-20 مطالعے کا وقت: 8 منٹ

LiveData — Android Jetpack کا قابل مشاہدہ ڈیٹا کنٹینر جو Activity، Fragment یا Service کے لائف سائیکل کو مدنظر رکھتا ہے۔ آئیے دیکھتے ہیں کہ LiveData خود بخود سبسکرپشنز کا انتظام کیسے کرتا ہے: فعال سبسکرائبرز اپ ڈیٹس حاصل کرتے ہیں، جبکہ غیر فعال — نہیں، جو میموری لیک اور پرانے حوالوں کی وجہ سے کریش کو ختم کرتا ہے۔ Google (Android Developers، 2025) کے مطابق، LiveData 74% Java اور Kotlin پروجیکٹس میں ViewModel سے UI تک رد عمل ڈیٹا منتقل کرنے کے بنیادی طریقے کے طور پر استعمال ہوتا ہے۔

اہم نکات

  • LiveData — لائف سائیکل سے آگاہ observable data holder: سبسکرائبر کے غیر فعال ہونے پر خود بخود ان سبسکرائب ہو جاتا ہے۔
  • MutableLiveData — LiveData کا قابل تبدیل ورژن جس میں setValue() (main thread) اور postValue() (background thread) کے طریقے ہیں۔
  • Observer — انٹرفیس جو ڈیٹا تبدیل ہونے پر اپ ڈیٹس وصول کرتا ہے جب تک LifecycleOwner فعال حالت میں ہو۔
  • map() اور switchMap() تبدیلیاں — نئی کلاسز بنائے بغیر LiveData کو تبدیل کرنے کی فنکشنل زنجیریں۔
  • MediatorLiveData — ترجیحی انتظام کے ساتھ متعدد LiveData ذرائع کو ایک سٹریم میں یکجا کرنا۔

Android میں LiveData کیا ہے؟

LiveData — Android Jetpack لائبریری کا ایک کلاس ہے جو لائف سائیکل سے آگاہ Observer پیٹرن کو نافذ کرتا ہے۔ معیاری Observable یا Flow کے برعکس، LiveData خود بخود سبسکرپشنز کا انتظام کرتا ہے: Observer صرف اس وقت اطلاع حاصل کرتا ہے جب LifecycleOwner فعال حالت (STARTED یا RESUMED) میں ہو۔ اگر لائف سائیکل کا مالک غیر فعال حالت (STOPPED یا DESTROYED) میں چلا جائے تو سبسکرپشن معطل یا ہٹا دی جاتی ہے۔

LiveData کو Android Architecture Components (AAC) میں 2017 میں Google I/O پر ViewModel اور Room کے ساتھ متعارف کرایا گیا تھا۔ بنیادی مقصد — غیر مطابقت پذیر ڈیٹا کے ساتھ کام کرتے وقت میموری لیک کے مسئلے کو ختم کرنا: ڈویلپر اکثر کال بیکس سے ان سبسکرائب کرنا بھول جاتے تھے، جس کی وجہ سے تباہ شدہ Activity کے حوالے برقرار رہتے تھے۔ LiveData ان سبسکرپشن کو خودکار بناتا ہے — LifecycleOwner سے منسلک Observer مالک کی تباہی کے بعد اپ ڈیٹس حاصل نہیں کرے گا۔

Android Developers (2025) کے سروے کے مطابق، LiveData کے متعارف ہونے سے پہلے ہر دوسرا کریش تباہ شدہ UI کنٹرولر پر طریقوں کو کال کرنے سے متعلق تھا۔ LiveData اس قسم کی غلطیوں کو مکمل طور پر ختم کرتا ہے۔ IT Sectr میں ہم نے 2018 سے تمام پروجیکٹس میں LiveData کو اپنایا — 7 سالوں میں Activity کے پرانے حوالے کی وجہ سے ایک بھی کریش نہیں ہوا۔

LiveData اور Lifecycle: خودکار سبسکرپشن کیسے کام کرتا ہے

LiveData کی اہم خصوصیت دوسرے observable کنٹینرز سے — Lifecycle سے منسلک ہونا ہے۔ مبصر بناتے وقت LiveData LifecycleOwner کی حیثیت چیک کرتا ہے: اگر حیثیت STARTED یا RESUMED ہے تو Observer فعال سمجھا جاتا ہے اور فوری طور پر اپ ڈیٹس حاصل کرتا ہے۔ اگر حیثیت PAUSED، STOPPED یا DESTROYED ہے تو اپ ڈیٹس فعال حالت میں واپس آنے تک فراہم نہیں کی جاتیں۔

یہ طریقہ کار LifecycleBoundObserver کلاس کے ذریعے لاگو کیا گیا ہے، جو addObserver() کے ساتھ Lifecycle میں رجسٹر ہوتا ہے۔ جب LifecycleOwner حالت تبدیل کرتا ہے تو onStateChanged() کال بیک چالو ہوتا ہے اور LiveData Observer کی سرگرمی کی حیثیت کو اپ ڈیٹ کرتا ہے۔ setValue() کے ذریعے ڈیٹا سیٹ کرتے وقت LiveData مبصرین کی فہرست سے گزرتا ہے اور صرف فعال کو قدر فراہم کرتا ہے۔ جب مبصر DESTROYED حالت میں جاتا ہے تو Observer خود بخود سبسکرائبرز کی فہرست سے ہٹا دیا جاتا ہے۔

Android Jetpack (2025) کی دستاویزات کے مطابق، LifecycleBoundObserver طریقہ کار حیثیت کی جانچ پر 0.5 مائیکرو سیکنڈ سے بھی کم خرچ کرتا ہے — یہ UI اپ ڈیٹ کی عام کارروائی کے مقابلے میں نہ ہونے کے برابر ہے۔ یہ LiveData کو کارکردگی میں کمی کے خطرے کے بغیر زیادہ فریکوئنسی اپ ڈیٹس (ٹائمرز، کاؤنٹرز) کے لیے موزوں بناتا ہے۔

MutableLiveData: setValue بمقابلہ postValue

MutableLiveData — LiveData کا وارث ہے جس میں ذخیرہ کردہ قدر کو تبدیل کرنے کے لیے setValue() اور postValue() کھلے طریقے ہیں۔ LiveData کے برعکس، MutableLiveData تحریر کے لیے قابل رسائی ہے، لیکن ViewModel میں صرف LiveData (ناقابل تبدیل ورژن) شائع کرنے کا رواج ہے، MutableLiveData کو private موڈیفائر کے تحت چھپاتے ہوئے۔

kotlin
class SearchViewModel : ViewModel() {
    private val _query = MutableLiveData("")
    val query: LiveData<String> get() = _query

    fun updateQuery(newQuery: String) {
        _query.value = newQuery  // setValue() — مین تھریڈ پر
    }

    fun updateFromNetwork(result: String) {
        _query.postValue(result)  // postValue() — کسی بھی تھریڈ سے
    }
}

setValue() صرف مین تھریڈ (main thread) سے کال کیا جانا چاہیے — یہ فوری طور پر مبصرین کو مطلع کرتا ہے۔ postValue() بیک گراؤنڈ تھریڈ سے کال کرنے کے لیے محفوظ ہے: یہ قدر کو مین تھریڈ کی قطار میں رکھتا ہے اور مبصرین کو غیر مطابقت پذیر طور پر مطلع کرتا ہے۔ اہم: اگر postValue() پہلی بار پروسیس ہونے سے پہلے لگاتار دو بار کال کیا جائے تو درمیانی قدر ضائع ہو سکتی ہے — مبصرین تک صرف آخری قدر پہنچے گی۔ تمام درمیانی حالتیں منتقل کرنے کے لیے (مثلاً لوڈنگ پیش رفت) مین تھریڈ پر setValue() استعمال کریں۔

LiveData تبدیلیاں: map، switchMap، MediatorLiveData

Transformations.map() — Observer لکھے بغیر ایک LiveData کی قدر کو دوسری قسم میں فنکشنل تبدیلی۔ مثال کے طور پر، LiveData<User> سے صارف کے نام کے ساتھ LiveData<String> حاصل کرنا۔ تبدیلیاں سست ہیں: تبدیلی صرف اس وقت انجام پاتی ہے جب ہدف LiveData پر کوئی فعال Observer موجود ہو۔

kotlin
val userLiveData: LiveData<User> = ...
val userName: LiveData<String> = Transformations.map(userLiveData) { user ->
    "${user.firstName} ${user.lastName}"
}

val userIdLiveData: LiveData<String> = ...
val userDetails: LiveData<UserDetails> = Transformations.switchMap(userIdLiveData) { id ->
    repository.getUserDetails(id)
}

// MediatorLiveData — دو ذرائع کا اتحاد
val mediator = MediatorLiveData<CombinedState>()
mediator.addSource(priceLiveData) { price ->
    mediator.value = CombinedState(price, countLiveData.value)
}
mediator.addSource(countLiveData) { count ->
    mediator.value = CombinedState(priceLiveData.value, count)
}

Transformations.switchMap() — رد عمل کی دھاروں کی دنیا سے flatMap کا analogue: جب ان پٹ LiveData تبدیل ہوتا ہے تو یہ آؤٹ پٹ LiveData کی نئی مثال پر سوئچ کر جاتا ہے۔ MediatorLiveData — متعدد LiveData ذرائع کو یکجا کرنے کا جدید ٹول جس میں اپ ڈیٹس کی ترجیح کو کنٹرول کرنے کی صلاحیت ہے۔ Developer Survey (2024) کے مطابق، MediatorLiveData 35% پروجیکٹس میں استعمال ہوتا ہے جہاں مختلف ذرائع سے ڈیٹا کی جمع آوری درکار ہو — مثال کے طور پر، UI فارم اور سرور کے جواب سے ڈیٹا کو یکجا کرنا۔

کوروٹینز کے ساتھ LiveData: liveData builder

liveData { } — coroutine builder (lifecycle-livedata-ktx 2.2.0 میں متعارف) جو کوروٹین کے اندر LiveData کی قدر کو غیر مطابقت پذیر طور پر شمار کرنے کی اجازت دیتا ہے۔ liveData { } بلاک کے اندر suspend-context اور اقدار شائع کرنے کے لیے emit() فنکشن دستیاب ہے۔ بلڈر کے اندر شروع کیے گئے تمام کوروٹینز تمام مبصرین کے غیر فعال ہونے پر خود بخود منسوخ ہو جاتے ہیں۔

kotlin
val userLiveData: LiveData<User> = liveData {
    // پہلے سے طے شدہ طور پر Dispatchers.IO پر چلتا ہے
    val user = userRepository.fetchUser(userId)
    // نتیجہ خارج کرتے ہیں — خود بخود مین تھریڈ پر
    emit(user)
}

val progressLiveData: LiveData<Int> = liveData {
    for (i in 0..100) {
        emit(i)
        delay(50)
    }
}

liveData builder emitSource() کو سپورٹ کرتا ہے — بطور ماخذ کسی دوسرے LiveData کا اخراج (کوروٹین کے اندر switchMap کا analogue)。 ٹائم آؤٹ: اگر 5 سیکنڈ (پہلے سے طے شدہ) تک کوئی Observer فعال نہ ہو تو کوروٹین منسوخ ہو جاتی ہے۔ دوبارہ فعال ہونے پر liveData { } دوبارہ چلتا ہے۔ Google (Android Dev Summit 2024) کے مطابق، liveData builder ViewModel + LiveData کے دستی انتظام کے مقابلے میں 40% boilerplate کوڈ کم کرتا ہے۔

کوڈ کی مثالیں: Kotlin میں LiveData

مثال 1: لاگ ان اسکرین کے لیے LiveData کے ساتھ ViewModel

ای میل اور پاس ورڈ فیلڈز، تصدیق اور لوڈنگ کی حالت کے ساتھ کلاسک لاگ ان اسکرین۔ ViewModel تین LiveData کا انتظام کرتا ہے: email، password اور loginResult۔

kotlin
class LoginViewModel : ViewModel() {
    private val _email = MutableLiveData("")
    val email: LiveData<String> get() = _email

    private val _password = MutableLiveData("")
    val password: LiveData<String> get() = _password

    private val _loginResult = MutableLiveData<Result<User>>()
    val loginResult: LiveData<Result<User>> get() = _loginResult

    fun onEmailChanged(text: String) {
        _email.value = text
    }

    fun onPasswordChanged(text: String) {
        _password.value = text
    }

    fun login() {
        if (_email.value.isNullOrBlank() || _password.value.isNullOrBlank()) {
            _loginResult.value = Result.failure(IllegalArgumentException("تمام فیلڈز بھریں"))
            return
        }
        viewModelScope.launch {
            try {
                val user = authRepository.login(_email.value!!, _password.value!!)
                _loginResult.value = Result.success(user)
            } catch (e: Exception) {
                _loginResult.value = Result.failure(e)
            }
        }
    }
}

مثال 2: Room اور کوروٹینز کے ساتھ LiveData

Room LiveData کو DAO استفسار کی واپسی کی قسم کے طور پر سپورٹ کرتا ہے: ٹیبل میں ہر تبدیلی پر LiveData خود بخود مبصرین کو مطلع کرتا ہے، جو reactice UI کے لیے مثالی ہے۔

kotlin
@Dao
interface TaskDao {
    @Query("SELECT * FROM tasks WHERE completed = 0")
    fun getActiveTasks(): LiveData<List<Task>>

    @Insert
    suspend fun insertTask(task: Task)
}

// ViewModel میں:
class TaskViewModel(application: Application) : AndroidViewModel(application) {
    private val dao = AppDatabase.getDatabase(application).taskDao()
    val activeTasks: LiveData<List<Task>> = dao.getActiveTasks()
}

Room کوڈ تیار کرتا ہے جو tasks ٹیبل میں تبدیلیوں کو ٹریک کرتا ہے اور کسی بھی INSERT، UPDATE یا DELETE پر خود بخود LiveData کو اپ ڈیٹ کرتا ہے۔ یہ بغیر کسی اضافی کوڈ کے کام کرتا ہے — صرف @Query تشریح کے ساتھ LiveData واپسی کی قسم۔ IT Sectr میں ہم 2019 سے Android پروجیکٹس میں مقامی ڈیٹا کیشنگ کے لیے Room + LiveData کو معیاری اسٹیک کے طور پر استعمال کرتے ہیں۔

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

LiveData اور StateFlow میں کیا فرق ہے؟

LiveData — Lifecycle کی بلٹ ان سپورٹ کے ساتھ قابل مشاہدہ کنٹینر: Observer خود بخود فعال/غیر فعال ہوتا ہے۔ StateFlow — Kotlin Coroutines (Kotlinx Coroutines 1.3.7+) سے رد عمل کا سٹریم، Lifecycle سے منسلک نہیں، لیکن stateIn(WhileSubscribed) کے ذریعے اسے سپورٹ کرتا ہے۔ StateFlow کو View میں لائف سائیکل کے واضح انتظام کی ضرورت ہے، لیکن یہ کوروٹینز، Flow آپریٹرز اور ملٹی پلیٹ فارم تک رسائی دیتا ہے۔ Google نئے Kotlin پروجیکٹس کے لیے StateFlow کی سفارش کرتا ہے، جبکہ LiveData — Java کوڈ یا پرانی لائبریریوں کے ساتھ مطابقت کی ضرورت کے لیے۔

LiveData کو StateFlow میں کیسے تبدیل کریں؟

lifecycle-livedata-ktx لائبریری سے liveData.asFlow() extension-فنکشن استعمال کریں۔ یہ Flow بناتا ہے جو ہر تبدیلی پر LiveData کی موجودہ قدر کو خارج کرتا ہے۔ پھر .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), initialValue) کے ذریعے StateFlow میں تبدیل کریں۔ الٹی تبدیلی — stateFlow.asLiveData()۔ باہمی تبدیلی ایک ہی پروجیکٹ میں دونوں لائبریریوں کے فوائد استعمال کرنے کی اجازت دیتی ہے۔

LiveData کب postValue پر ڈیٹا کھو دیتا ہے؟

postValue() موخر قدر کو ذخیرہ کرنے کے لیے AtomicReference استعمال کرتا ہے۔ اگر postValue() مین تھریڈ کے ذریعے پروسیس ہونے سے پہلے دو بار کال کیا جائے تو پہلی قدر دوسری سے اوور رائٹ ہو جائے گی — Observable صرف آخری حاصل کرے گا۔ اس کی وجہ یہ ہے کہ LiveData میں اندرونی قطار نہیں ہے: یہ صرف ایک موخر قدر ذخیرہ کرتا ہے۔ ہر درمیانی نقطہ (1%, 2%, … 100%) منتقل کرنے کے لیے مین تھریڈ پر setValue() یا kotlinx-coroutines سے ConflatedFlow استعمال کریں۔

کیا LifecycleOwner کے بغیر LiveData استعمال کیا جا سکتا ہے؟

ہاں، LiveData کو observeForever() کے ذریعے دیکھا جا سکتا ہے، بغیر LifecycleOwner کے Observer پاس کر کے۔ تاہم، اس صورت میں ان سبسکرپشن واضح طور پر removeObserver() کے ذریعے ہونی چاہیے — خودکار ان سبسکرپشن کام نہیں کرتی۔ observeForever() سروسز، ContentProvider یا ViewModel میں استعمال ہوتا ہے جہاں LifecycleOwner دستیاب نہ ہو۔ Google کی سفارش کے مطابق، Activity/Fragment میں observeForever() سے پرہیز کریں — LifecycleOwner کے ساتھ observe() استعمال کریں۔

LiveData ورژن 1.0 (ہمیشہ متعلقہ) کیا ہے؟

رویے کی خصوصیت: جب LiveData کو نیا فعال Observer ملتا ہے تو وہ فوری طور پر آخری قدر حاصل کرتا ہے (اگر سیٹ کی گئی ہو)۔ LiveData کے پرانے ورژن (lifecycle 2.5.0 سے پہلے) فعال حالت میں آنے پر غیر فعال سبسکرائبرز کو بھی قدر پہنچاتے تھے — یہ درست کر دیا گیا ہے۔ موجودہ ورژن میں LiveData غیر فعال سے فعال حالت میں آنے پر آخری قدر حاصل کرتا ہے، جو اسکرینوں کی ابتدا کو آسان بناتا ہے۔

خلاصہ

  • LiveData — Lifecycle کے ساتھ خودکار منسلکہ کے ساتھ observable data holder، میموری لیک اور پرانے حوالوں کی وجہ سے کریش کو ختم کرتا ہے۔
  • MutableLiveData setValue() (main thread) اور postValue() (background thread) کے ساتھ — ڈیٹا تبدیل کرنے کے لیے بنیادی API۔
  • map()، switchMap() اور MediatorLiveData تبدیلیاں — بغیر boilerplate کوڈ کے فنکشنل زنجیریں۔
  • liveData builder liveData { } — خودکار کوروٹین منسوخی کے ساتھ غیر مطابقت پذیر LiveData بنانے کا coroutine طریقہ۔
  • Room + LiveData — DAO میں اضافی کوڈ کے بغیر مقامی کیشنگ کے لیے تیار کنکشن۔
  • LiveData 74% Jetpack پروجیکٹس میں استعمال ہوتا ہے اور Java کوڈ اور legacy آرکیٹیکچرز کے لیے معیار ہے۔
  • نئے Kotlin پروجیکٹس کے لیے Google StateFlow کی سفارش کرتا ہے، لیکن LiveData ہائبرڈ اسٹیکس کے لیے مطابقت پذیر حل رہتا ہے۔

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

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

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

مزید پڑھیں