LiveData: bu nədir, Android Architecture komponenti

Müəllif: IT Sectr Dərc olunub: 2026-02-20 Oxuma vaxtı: 8 dəq

LiveData — Android Jetpack-dən Activity, Fragment və ya Service-in həyat dövrünü nəzərə alan müşahidə edilən məlumat konteyneri. LiveData-nın abunəlikləri avtomatik idarə etməsini izah edəcəyik: aktiv abunəçilər yeniləmələri alır, qeyri-aktivlər isə almır, bu da yaddaş sızmalarını və köhnəlmiş istinadlar səbəbindən crash-ləri aradan qaldırır. Google məlumatlarına görə (Android Developers, 2025), LiveData Java və Kotlin layihələrinin 74%-də ViewModel-dən UI-ə reaktiv məlumat ötürmənin əsas üsulu kimi istifadə olunur.

Əsas məqamlar

  • LiveData — həyat dövrünü nəzərə alan müşahidə edilən məlumat konteyneri: abunəçi qeyri-aktiv olduqda avtomatik abunəlikdən çıxarılır.
  • MutableLiveData — LiveData-nın dəyişdirilə bilən versiyası setValue() (əsas thread) və postValue() (fon thread) metodları ilə.
  • Observer — LifecycleOwner aktiv vəziyyətdə olduğu müddətdə məlumat dəyişdikdə yeniləmələri alan interfeys.
  • map()switchMap() transformasiyaları — yeni siniflər yaratmadan LiveData-nın funksional çevrilmə zəncirləri.
  • MediatorLiveData — bir neçə LiveData mənbəyini prioritet idarəetmə ilə bir axında birləşdirmək.

Android-də LiveData nədir?

LiveData — Android Jetpack kitabxanasından həyat dövrünü nəzərə alan Observer nümunəsini həyata keçirən sinifdir. Standart Observable və ya Flow-dan fərqli olaraq, LiveData abunəlikləri avtomatik idarə edir: Observer yalnız LifecycleOwner aktiv vəziyyətdə olduqda (STARTED və ya RESUMED) bildirişlər alır. Həyat dövrü sahibi qeyri-aktiv vəziyyətə (STOPPED və ya DESTROYED) keçərsə, abunəlik dayandırılır və ya silinir.

LiveData Android Architecture Components (AAC) çərçivəsində 2017-ci ildə Google I/O konfransında ViewModel və Room ilə birlikdə təqdim edilmişdir. Əsas məqsəd asinxron məlumatlarla işləyərkən yaddaş sızmaları problemini aradan qaldırmaq idi: tərtibatçılar tez-tez callback-lərdən çıxmağı unudurdular, bu da məhv edilmiş Activity-lərə istinadların saxlanmasına səbəb olurdu. LiveData çıxmağı avtomatlaşdırır — LifecycleOwner ilə əlaqəli Observer sahib məhv edildikdən sonra yeniləmələri almır.

Android Developers (2025) sorğusuna görə, LiveData tətbiq edilməzdən əvvəl hər ikinci crash məhv edilmiş UI kontrollerində metodların çağırılması ilə əlaqəli idi. LiveData bu səhv sinfini tamamilə aradan qaldırır. IT Sectr olaraq biz LiveData-nı 2018-ci ildən bütün layihələrimizə tətbiq etdik — 7 il ərzində Activity-yə köhnəlmiş istinad səbəbindən bir dənə də olsun crash baş vermədi.

LiveData və Lifecycle: avtomatik abunəlik necə işləyir

LiveData-nın digər müşahidə konteynerlərindən əsas fərqi — Lifecycle ilə əlaqələndirilməsidir. Müşahidəçi yaradılarkən LiveData LifecycleOwner statusunu yoxlayır: status STARTED və ya RESUMED olarsa, Observer aktiv sayılır və dərhal yeniləmələri alır. Status PAUSED, STOPPED və ya DESTROYED olarsa, yeniləmələr aktiv vəziyyətə qayıdana qədər çatdırılmır.

Mexanizm LifecycleBoundObserver sinfi vasitəsilə həyata keçirilir, o addObserver() ilə Lifecycle-də qeydiyyatdan keçir. LifecycleOwner vəziyyət dəyişdikdə onStateChanged() callback-i işə düşür və LiveData Observer-in aktivlik statusunu yeniləyir. setValue() vasitəsilə məlumat təyin edilərkən LiveData müşahidəçilər siyahısını keçir və dəyəri yalnız aktiv olanlara çatdırır. Müşahidəçi DESTROYED vəziyyətinə keçdikdə Observer avtomatik olaraq abunəçilər siyahısından silinir.

Android Jetpack sənədlərinə görə (2025), LifecycleBoundObserver mexanizmi status yoxlamasına 0,5 µs-dən az sərf edir — bu, tipik UI yeniləmə əməliyyatı ilə müqayisədə əhəmiyyətsiz dərəcədə kiçikdir. Bu, LiveData-nı performans itkisi riski olmadan yüksək tezlikli yeniləmələr (taymerlər, sayğaclar) üçün uyğun edir.

MutableLiveData: setValue vs postValue

MutableLiveData — saxlanılan dəyəri dəyişmək üçün açıq setValue()postValue() metodları olan LiveData varisidir. LiveData-dan fərqli olaraq, MutableLiveData yazmaq üçün əlçatandır, lakin ViewModel-də yalnız LiveData-nı (dəyişməz versiya) dərc etmək, MutableLiveData-nı isə private modifikatoru altında gizlətmək adətdir.

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

    fun updateQuery(newQuery: String) {
        _query.value = newQuery  // setValue() — əsas thread-də
    }

    fun updateFromNetwork(result: String) {
        _query.postValue(result)  // postValue() — istənilən thread-dən
    }
}

setValue() yalnız əsas thread-dən çağırılmalıdır — o dərhal müşahidəçilərə bildiriş göndərir. postValue() fon thread-dən çağırış üçün təhlükəsizdir: dəyəri əsas thread-in növbəsinə yerləşdirir və müşahidəçilərə asinxron bildiriş göndərir. Vacib: əgər postValue() birincinin işlənməsindən əvvəl iki dəfə çağırılırsa, aralıq dəyər itirilə bilər — müşahidəçilər yalnız sonuncunu alacaq. Bütün aralıq vəziyyətləri ötürmək üçün (məsələn, yükləmə gedişatı) əsas thread-də setValue() istifadə edin.

LiveData transformasiyaları: map, switchMap, MediatorLiveData

Transformations.map() — Observer yazmadan bir LiveData dəyərini başqa tipə funksional çevirmə. Məsələn, LiveData<User>-dən istifadəçi adı ilə LiveData<String> əldə etmək. Transformasiyalar tənbəldir: çevirmə yalnız hədəf LiveData-da aktiv Observer olduqda icra olunur.

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 mənbəyin birləşdirilməsi
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() — reaktiv axınlar dünyasından flatMap-in analoqu: giriş LiveData dəyişdikdə çıxış LiveData-nın yeni nümunəsinə keçir. MediatorLiveData — yeniləmə prioritetini idarə etmək imkanı ilə bir neçə LiveData mənbəyini birləşdirmək üçün qabaqcıl alət. Developer Survey (2024) məlumatına görə, MediatorLiveData müxtəlif mənbələrdən məlumat aqreqasiyası tələb edən layihələrin 35%-də istifadə olunur — məsələn, UI forma məlumatları və server cavabının birləşdirilməsi.

Korutinlərlə LiveData: liveData builder

liveData { } — korutina daxilində LiveData dəyərini asinxron hesablamağa imkan verən coroutine builder (lifecycle-livedata-ktx 2.2.0-da təqdim edilmişdir). liveData { } bloku daxilində suspend konteksti, həmçinin dəyərləri dərc etmək üçün emit() funksiyası mövcuddur. Builder daxilində işə salınmış bütün korutinlar bütün müşahidəçilər qeyri-aktiv olduqda avtomatik ləğv edilir.

kotlin
val userLiveData: LiveData<User> = liveData {
    // Dispatchers.IO-da standart olaraq icra olunur
    val user = userRepository.fetchUser(userId)
    // Nəticəni emit edirik — avtomatik əsas thread-də
    emit(user)
}

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

liveData builder emitSource() funksiyasını dəstəkləyir — başqa LiveData-nın mənbə kimi emit edilməsi (korutina daxilində switchMap analoqu). Timeout: heç bir Observer 5 saniyə (standart) aktiv olmazsa, korutina ləğv edilir. Yenidən aktivləşdirmədə liveData { } əvvəldən icra olunur. Google məlumatına görə (Android Dev Summit 2024), liveData builder əl ilə ViewModel + LiveData idarəsi ilə müqayisədə 40% şablon kodu azaldır.

Kod nümunələri: Kotlin-də LiveData

Nümunə 1: Giriş ekranı üçün ViewModel LiveData ilə

Email və şifrə sahələri, validasiya və yükləmə vəziyyəti olan klassik giriş ekranı. ViewModel üç LiveData idarə edir: email, password və 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("Bütün sahələri 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)
            }
        }
    }
}

Nümunə 2: LiveData Room və korutinlərlə

Room LiveData-nı DAO sorğusunun qaytarılan tipi kimi dəstəkləyir: cədvəl hər dəfə dəyişdikdə LiveData avtomatik müşahidəçilərə bildiriş göndərir, bu da reaktiv UI üçün idealdır.

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

    @Insert
    suspend fun insertTask(task: Task)
}

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

Room tasks cədvəlindəki dəyişiklikləri izləyən kod yaradır və hər INSERT, UPDATE və ya DELETE zamanı LiveData-nı avtomatik yeniləyir. Bu əlavə kod olmadan işləyir — yalnız LiveData qaytarılan tipi ilə @Query annotasiyası kifayətdir. IT Sectr olaraq biz 2019-cu ildən Android layihələrində lokalkeşdə məlumat saxlama üçün Room + LiveData standart yığınından istifadə edirik.

Tez-tez verilən suallar

LiveData və StateFlow arasında nə fərq var?

LiveData — daxili Lifecycle dəstəyi olan müşahidə konteyneri: Observer avtomatik aktivləşir/deaktivləşir. StateFlow — Kotlin Coroutines-dən (Kotlinx Coroutines 1.3.7+) reaktiv axın, Lifecycle-ə bağlı deyil, lakin stateIn(WhileSubscribed) vasitəsilə bunu dəstəkləyir. StateFlow View-də həyat dövrünün açıq idarə edilməsini tələb edir, lakin korutinlərə, Flow operatorlarına və çoxplatformalılığa çıxış verir. Google yeni Kotlin layihələri üçün StateFlow-u, Java kodu və ya köhnə kitabxanalarla uyğunluq üçün LiveData-nı tövsiyə edir.

LiveData-nı StateFlow-a necə çevirmək olar?

lifecycle-livedata-ktx kitabxanasından liveData.asFlow() genişləndirmə funksiyasından istifadə edin. O, hər dəyişiklikdə LiveData-nın cari dəyərini emit edən Flow yaradır. Sonra .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), initialValue) ilə StateFlow-a çevirin. Əks çevirmə — stateFlow.asLiveData(). Qarşılıqlı konvertasiya bir layihədə hər iki kitabxananın üstünlüklərindən istifadə etməyə imkan verir.

LiveData nə vaxt postValue-da məlumat itirir?

postValue() təxirə salınmış dəyəri saxlamaq üçün AtomicReference istifadə edir. Əgər postValue() əsas thread tərəfindən işlənmədən əvvəl iki dəfə çağırılırsa, birinci dəyər ikinci ilə üzərinə yazılacaq — Observable yalnız sonuncunu alacaq. Bu, LiveData-nın daxili növbəsinin olmaması ilə bağlıdır: o yalnız bir təxirə salınmış dəyər saxlayır. Hər aralıq nöqtəni (1%, 2%, … 100%) ötürmək üçün əsas thread-də setValue() və ya kotlinx-coroutines-dən ConflatedFlow istifadə edin.

LiveData-nı LifecycleOwner olmadan istifadə etmək olar?

Bəli, LiveData-nı observeForever() vasitəsilə müşahidə etmək olar, Observer-i LifecycleOwner olmadan ötürməklə. Lakin bu halda abunəlikdən çıxma removeObserver() ilə açıq şəkildə aparılmalıdır — avtomatik çıxma işləmir. observeForever() LifecycleOwner-in mövcud olmadığı servislərdə, ContentProvider-də və ya ViewModel-də tətbiq olunur. Google tövsiyəsinə əsasən, Activity/Fragment-də observeForever()-dən çəkinin — LifecycleOwner ilə observe() istifadə edin.

LiveData versiyası 1.0 nədir (həmişə aktual)?

Davranış xüsusiyyəti: LiveData yeni aktiv Observer aldıqda dərhal son dəyəri alır (əgər təyin edilibsə). LiveData-nın köhnə versiyaları (lifecycle 2.5.0-dan əvvəl) aktiv vəziyyətə keçərkən hətta qeyri-aktiv abunəçilərə də dəyər çatdırırdı — bu düzəldilib. Cari versiyada LiveData son dəyəri qeyri-aktivdən aktiv vəziyyətə KEÇİD zamanı alır, bu da ekranların inisializasiyasını sadələşdirir.

Nəticə

  • LiveData — Lifecycle-ə avtomatik bağlanma ilə yaddaş sızmalarını və köhnəlmiş istinadlar səbəbindən crash-ləri aradan qaldıran müşahidə edilən məlumat konteyneri.
  • MutableLiveData setValue() (əsas thread) və postValue() (fon thread) ilə — məlumat dəyişdirmək üçün əsas API.
  • map(), switchMap()MediatorLiveData transformasiyaları — şablon kodu olmayan funksional zəncirlər.
  • liveData builder liveData { } — korutinlərin avtomatik ləğvi ilə asinxron LiveData yaratmaq üçün korutin yanaşması.
  • Room + LiveData — DAO-da əlavə kod olmadan lokal keşləmə üçün hazır birləşmə.
  • LiveData Jetpack layihələrinin 74%-də istifadə olunur və Java kodu və legacy arxitekturalar üçün standart olaraq qalır.
  • Yeni Kotlin layihələri üçün Google StateFlow-u tövsiyə edir, lakin LiveData hibrid yığınlar üçün uyğun həll olaraq qalır.

Açar təslim mobil tətbiq hazırlayacağıq

IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.

Layihəni müzakirə et

Həm də oxuyun