LiveData: nedir, Android Architecture bileşeni

Yazar: IT Sectr Yayınlanma: 2026-02-20 Okuma süresi: 8 dk

LiveData, Android Jetpack'ten Activity, Fragment veya Service'in yaşam döngüsünü dikkate alan gözlemlenebilir bir veri kapsayıcısıdır. LiveData'nın abonelikleri nasıl otomatik olarak yönettiğini keşfedelim: aktif aboneler güncellemeleri alır, pasif olanlar almaz, bu da eski referanslar nedeniyle bellek sızıntılarını ve çökmeleri ortadan kaldırır. Google'a (Android Developers, 2025) göre LiveData, Java ve Kotlin projelerinin %74'ünde ViewModel'den UI'ya reaktif veri aktarımının ana yolu olarak kullanılır.

Önemli Noktalar

  • LiveData — yaşam döngüsü farkındalığına sahip gözlemlenebilir veri tutucu: abone pasif olduğunda otomatik olarak abonelikten çıkar.
  • MutableLiveData — setValue() (ana iş parçacığı) ve postValue() (arka plan iş parçacığı) metotlarıyla LiveData'nın değiştirilebilir sürümü.
  • Observer — LifecycleOwner aktif durumdayken veri değiştiğinde güncellemeleri alan arayüz.
  • map() ve switchMap() dönüşümleri — yeni sınıflar oluşturmadan LiveData'yı dönüştürmek için işlevsel zincirler.
  • MediatorLiveData — öncelik yönetimi ile birden çok LiveData kaynağını tek bir akışta birleştirme.

Android'de LiveData Nedir?

LiveData, Android Jetpack kütüphanesinden, yaşam döngüsü farkındalığına sahip Observer desenini uygulayan bir sınıftır. Standart Observable veya Flow'un aksine, LiveData abonelikleri otomatik olarak yönetir: bir Observer, yalnızca LifecycleOwner aktif durumdayken (STARTED veya RESUMED) bildirim alır. Yaşam döngüsü sahibi pasif bir duruma (STOPPED veya DESTROYED) geçerse, abonelik duraklatılır veya kaldırılır.

LiveData, 2017'de Google I/O'da ViewModel ve Room ile birlikte Android Architecture Components (AAC)'de tanıtıldı. Ana motivasyon, asenkron verilerle çalışırken bellek sızıntılarını ortadan kaldırmaktı: geliştiriciler genellikle geri aramalardan abonelikten çıkmayı unutuyordu, bu da yok edilmiş Activity'lere referansların tutulmasına yol açıyordu. LiveData, abonelikten çıkmayı otomatik hale getirir — bir LifecycleOwner ile ilişkilendirilmiş Observer, sahip yok edildikten sonra güncelleme almaz.

Android Developers anketine (2025) göre, LiveData benimsenmeden önce her iki çökmeden biri, yok edilmiş bir UI denetleyicisinde metot çağrılmasıyla ilgiliydi. LiveData bu hata sınıfını tamamen ortadan kaldırır. IT Sectr'da, 2018'den beri tüm projelerde LiveData'yı uyguladık — 7 yılı aşkın süredir eski Activity referansları nedeniyle sıfır çökme.

LiveData ve Lifecycle: otomatik abonelik nasıl çalışır

LiveData'nın temel farkı, diğer gözlemlenebilir kapsayıcılardan Lifecycle'a bağlı olmasıdır. Bir gözlemci oluşturulduğunda, LiveData LifecycleOwner'ın durumunu kontrol eder: durum STARTED veya RESUMED ise, Observer aktif kabul edilir ve güncellemeleri hemen alır. Durum PAUSED, STOPPED veya DESTROYED ise, aktif duruma dönene kadar güncellemeler iletilmez.

Mekanizma, addObserver() kullanarak Lifecycle'a kaydolan LifecycleBoundObserver sınıfı aracılığıyla uygulanır. LifecycleOwner durum değiştirdiğinde, onStateChanged() geri çağırması tetiklenir ve LiveData, Observer'ın etkinlik durumunu günceller. Veriler setValue() ile ayarlandığında, LiveData gözlemci listesini dolaşır ve değeri yalnızca aktif olanlara iletir. Bir gözlemci DESTROYED durumuna geçtiğinde, Observer otomatik olarak abone listesinden kaldırılır.

Android Jetpack belgelerine (2025) göre, LifecycleBoundObserver mekanizması durum kontrolü başına 0,5 µs'den az tüketir — tipik bir UI güncelleme işlemine kıyasla ek yük ihmal edilebilir düzeydedir. Bu, LiveData'yı performans düşüşü riski olmadan yüksek frekanslı güncellemeler (zamanlayıcılar, sayaçlar) için uygun hale getirir.

MutableLiveData: setValue vs postValue

MutableLiveData, depolanan değeri değiştirmek için genel setValue() ve postValue() metotlarına sahip LiveData'nın bir alt sınıfıdır. LiveData'nın aksine, MutableLiveData yazılabilir, ancak ViewModel'de yalnızca LiveData'yı (değişmez sürüm) açığa çıkarmak ve MutableLiveData'yı private değiştiricisinin arkasında gizlemek yaygın bir uygulamadır.

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

    fun updateQuery(newQuery: String) {
        _query.value = newQuery  // setValue() — ana iş parçacığında
    }

    fun updateFromNetwork(result: String) {
        _query.postValue(result)  // postValue() — herhangi bir iş parçacığından
    }
}

setValue() yalnızca ana iş parçacığından çağrılmalıdır — gözlemcileri hemen bilgilendirir. postValue(), arka plan iş parçacığından çağırmak için güvenlidir: değeri ana iş parçacığının kuyruğuna koyar ve gözlemcileri asenkron olarak bilgilendirir. Önemli: postValue(), ilki işlenmeden önce arka arkaya iki kez çağrılırsa, ara değer kaybolabilir — gözlemcilere yalnızca son değer ulaşır. Tüm ara durumları (örneğin, yükleme ilerlemesi) iletmek için ana iş parçacığında setValue() kullanın.

LiveData Dönüşümleri: map, switchMap, MediatorLiveData

Transformations.map() — Observer yazmadan bir LiveData değerinin başka bir türe işlevsel dönüşümü. Örneğin, LiveData<User>'dan kullanıcı adıyla LiveData<String> almak. Dönüşümler tembeldir: dönüşüm yalnızca hedef LiveData'da aktif bir Observer olduğunda gerçekleştirilir.

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 — iki kaynağın birleştirilmesi
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() — reaktif akışlar dünyasından flatMap'in bir benzeri: girdi LiveData değiştiğinde, çıktı LiveData'nın yeni bir örneğine geçer. MediatorLiveData — güncelleme önceliğini yönetme yeteneği ile birden çok LiveData kaynağını birleştirmek için gelişmiş bir araçtır. Developer Survey (2024)'e göre MediatorLiveData, farklı kaynaklardan veri toplama gerektiren projelerin %35'inde kullanılır — örneğin, UI form verileri ve sunucu yanıtını birleştirme.

LiveData coroutine'ler ile: liveData builder

liveData { } — bir coroutine oluşturucudur (lifecycle-livedata-ktx 2.2.0'da tanıtıldı) ve bir coroutine içinde LiveData değerlerinin asenkron olarak hesaplanmasına olanak tanır. liveData { } bloğu içinde, bir suspend bağlamı ve değerleri yayınlamak için emit() işlevi bulunur. Oluşturucu içinde başlatılan tüm coroutine'ler, tüm gözlemciler pasif hale geldiğinde otomatik olarak iptal edilir.

kotlin
val userLiveData: LiveData<User> = liveData {
    // Varsayılan olarak Dispatchers.IO'da yürütülür
    val user = userRepository.fetchUser(userId)
    // Sonuç yayınlanıyor — otomatik olarak ana iş parçacığında
    emit(user)
}

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

liveData builder, emitSource()'ı destekler — kaynak olarak başka bir LiveData yayını (bir coroutine içindeki switchMap'e benzer). Zaman aşımı: 5 saniye (varsayılan) boyunca hiçbir Observer aktif değilse, coroutine iptal edilir. Yeniden etkinleştirildiğinde, liveData { } yeniden çalıştırılır. Google'a (Android Dev Summit 2024) göre liveData builder, manuel ViewModel + LiveData yönetimine kıyasla kalıplaşmış kodu %40 azaltır.

Kod örnekleri: Kotlin'de LiveData

Örnek 1: Giriş ekranı için LiveData ile ViewModel

E-posta ve şifre alanları, doğrulama ve yükleme durumu içeren klasik bir giriş ekranı. ViewModel üç LiveData'yı yönetir: email, password ve 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("Tüm alanları doldurun"))
            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)
            }
        }
    }
}

Örnek 2: LiveData, Room ve coroutine'ler ile

Room, DAO sorguları için dönüş türü olarak LiveData'yı destekler: tablo her değiştiğinde LiveData otomatik olarak gözlemcileri bilgilendirir, bu da reaktif UI için idealdir.

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

    @Insert
    suspend fun insertTask(task: Task)
}

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

Room, tasks tablosundaki değişiklikleri izleyen ve her INSERT, UPDATE veya DELETE'te LiveData'yı otomatik olarak güncelleyen kod oluşturur. Bu ek kod olmadan çalışır — yalnızca LiveData dönüş türüyle @Query ek açıklaması yeterlidir. IT Sectr'da, 2019'dan beri Android projelerinde yerel veri önbellekleme için standart yığın olarak Room + LiveData kullanıyoruz.

Sıkça Sorulan Sorular

LiveData ve StateFlow arasındaki fark nedir?

LiveData, yerleşik Lifecycle desteğine sahip gözlemlenebilir bir kapsayıcıdır: Observer otomatik olarak etkinleştirilir/devre dışı bırakılır. StateFlow, Kotlin Coroutines'den (Kotlinx Coroutines 1.3.7+) reaktif bir akıştır, Lifecycle'a bağlı değildir ancak stateIn(WhileSubscribed) aracılığıyla bunu destekler. StateFlow, View'da açık yaşam döngüsü yönetimi gerektirir, ancak coroutine'lere, Flow operatörlerine ve çoklu platform yeteneklerine erişim sağlar. Google, yeni Kotlin projeleri için StateFlow'u, Java kodu veya eski kütüphanelerle uyumluluk gerektiğinde LiveData'yı önerir.

LiveData StateFlow'a nasıl dönüştürülür?

lifecycle-livedata-ktx kütüphanesinden liveData.asFlow() uzantı işlevini kullanın. Her değişiklikte geçerli LiveData değerini yayan bir Flow oluşturur. Ardından .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), initialValue) ile StateFlow'a dönüştürün. Ters dönüşüm stateFlow.asLiveData()'dır. Karşılıklı dönüşüm, tek bir projede her iki kütüphanenin avantajlarından yararlanmayı sağlar.

LiveData postValue ile ne zaman veri kaybeder?

postValue(), bekleyen değeri depolamak için AtomicReference kullanır. Ana iş parçacığı işlemeden önce postValue() iki kez çağrılırsa, ilk değer ikinci tarafından üzerine yazılır — Observer yalnızca son değeri alır. Bunun nedeni LiveData'nın dahili bir kuyruğunun olmamasıdır: yalnızca bir bekleyen değer depolar. Her ara noktayı (%1, %2, … %100) iletmek için ana iş parçacığında setValue() veya kotlinx-coroutines'den ConflatedFlow kullanın.

LiveData LifecycleOwner olmadan kullanılabilir mi?

Evet, LiveData, LifecycleOwner olmadan bir Observer geçirerek observeForever() aracılığıyla gözlemlenebilir. Ancak bu durumda abonelikten çıkma, removeObserver() aracılığıyla açık olmalıdır — otomatik abonelikten çıkma çalışmaz. observeForever(), LifecycleOwner'ın bulunmadığı servislerde, ContentProvider'da veya ViewModel'de kullanılır. Google'ın önerisine göre, Activity/Fragment'te observeForever()'dan kaçının — LifecycleOwner ile observe() kullanın.

LiveData sürüm 1.0 davranışı nedir (her zaman geçerli)?

Davranış özelliği: LiveData yeni bir aktif Observer aldığında, hemen en son değeri (ayarlanmışsa) alır. LiveData'nın eski sürümleri (lifecycle 2.5.0 öncesi), aktif duruma geçerken pasif abonelere bile değer iletiyordu — bu düzeltildi. Mevcut sürümde LiveData, pasiften aktife geçerken en son değeri iletir, bu da ekran başlatmayı basitleştirir.

Özet

  • LiveData — otomatik Lifecycle bağlamalı gözlemlenebilir veri tutucu, eski referanslar nedeniyle bellek sızıntılarını ve çökmeleri ortadan kaldırır.
  • MutableLiveData setValue() (ana iş parçacığı) ve postValue() (arka plan iş parçacığı) ile — veri değiştirmek için ana API.
  • map(), switchMap() ve MediatorLiveData dönüşümleri — kalıplaşmış kod olmadan işlevsel zincirler.
  • liveData builder liveData { } — otomatik coroutine iptali ile asenkron LiveData oluşturmak için coroutine yaklaşımı.
  • Room + LiveData — DAO'da ek kod olmadan yerel önbellekleme için hazır paket.
  • LiveData, Jetpack projelerinin %74'ünde kullanılır ve Java kodu ve eski mimariler için standart olmaya devam eder.
  • Yeni Kotlin projeleri için Google StateFlow'u önerir, ancak LiveData hibrit yığınlar için uyumlu bir çözüm olmaya devam eder.

Anahtar teslim bir mobil uygulama geliştireceğiz

IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.

Projeyi tartış

Ayrıca okuyun