Android LiveData Kullanımı
Merhabalar, bu yazımda Android Architecture Components in önemli bir bileşeni olan LiveData dan bahsedeceğim. Biraz ağır bir konu olabilir. Olabildiğince kod tarafında da açıklamalarda bulunacağım. Yani ne anlatıyorsun sen kardeşim derseniz biraz haklı olabilirsiniz. Hikaye kısımlarında bende sıkılıyorum çünkü.
LiveData, gözlemlenebilir bir veri tutma sınıfıdır. Peki daha önce sözünü etmiş olduğum Observable dan farkı nedir? LiveData Observable’ın aksine LifeCycle-Aware dir. Yani Activity, Fragment ya da Servis gibi bileşenlerin yaşam döngülerine karşılık hareket edebilir. Bu özellik LiveData’nın sadece aktif yaşam döngüsündeki bileşemlerin gözlemleyicilerini güncelleştirmesini sağlar.
LiveData Observer sınıfından türetilen bir observer ın aktif yaşam döngüsünde olduğunu varsayar. Yani LifeCycle state inin STARTED yada RESUMED olduğu durumlarda bu observer’ı güncellemelerden haberdar eder.Bahsedilen bu observer LifeCycleOwner arayüzünü implemente eden bir nesne ile eşleştirilerek kayıt edilebilir. Bu durum sayesinde LifeCycleOwner olan component ın state i DESTROY olduğu zaman observer ile LifeCycleOwner’a sahip olan componentin arasındaki bağın kalkmasını sağlar. Yani örneğin bir Activity’de LiveData’nın değişikli gözlemleyen bir Observer varsa, Activity destroy olduğu zaman bu değişikliği gözlemleyen bağ da ortadan kaldırılır.
LiveData nın Avantajları
- Kullanıcı arayüzü ile veri durumunun eşleşmesini garanti eder;
LiveData observer mimarisini örnek alır. LifeCycle durumu değiştiği zaman bu durumu observer’a bildirir. Kullanıcı arayüzleri de bu Observer içerisinde güncellenebilir. Kullanıcı arayüzünü her defasında güncellemek yerine, Observer her defasında bunu sizin yerinize yapabilir
- Memory Leak yoktur.
Observer lar LifeCycle nesnelerine bağlıdır, ve bağlı oldukları Componentler DESTROY olurlarsa otomatik olarak temizleme işlerini kendileri yaparlar.
- Stopped durumdaki Activityler de crashleri önler
Eğer bir Activity inaktif bir durumdaysa, bu Activity herhangi bir LiveData event i almaz. Böylelikle durur konumda iken güncelleme yapmaya çalışmaz.
- Her zaman güncel veri vardır.
Eğer yaşam döngüsü inaktif durumda olsa bile, bu yaşam döngüsü aktif olana kadar en son kaydedilen veri kullanılır.
- Düzgün bir biçimde konfigürasyon değişikliklerinin yapılmasını sağlar.
Eğer bir activity ya da fragment cihazın portrait mode dan landscape mode çevrilmesi gibi bir konfigürasyon değişikliğinden dolayı yeniden oluşturulursa, en son kaydedilen veriler saklanır.
İşin hikaye kısmını anlattık. Şimdi artık biraz kod yazalım. Öncelikle gerekli olan dependencylerimizi ekleyelim ve bir Activiy de LiveData daki değişiklikleri gözlemleyecek bir Observer nasıl oluşturulur, bu değişiklikler nasıl alınır onu gösterelim.
implementation 'androidx.lifecycle:lifecycle-extensions:2.1.0-alpha03'
Yukdarıdaki dependency i kullanabilmek için projenizi AndroidX’e migrate etmeniz gereklidir.
Öncelikle arkadaşlar burada ViewModel kullanılmıştır. ViewModel den bahseden bir makale ileride yazmayı düşünüyorum. O yüzden ViewModel ile ilgili satırları görmezden gelmenizi rica edeceğim. Zaten diğer şeyleri tamamıyla açıklayacağım.
Toast.makeText(this, model.getCurrentDate().getValue(), Toast.LENGTH_LONG).show();
Toast mesajı konfigürasyon değişikliklerinde en son olan verinin ne olduğunu ekrana göstermek için kullanılmıştır.
final Observer<String> dateObserver = new Observer<String>() {
@Override
public void onChanged(@Nullable String date) {
dateTextView.setText(date);
}
};
Yukarıda bir observer tanımlaması gösterilmiştir. Bu observer ımız bir String değer gözlemleyecektir ve bu String değerin her değişmesi sonucu dateTextView isimli TextView güncellenecektir.
model.getCurrentDate().observe(this, dateObserver);
Bu satırda ise observer ile getCurrentDate() fonksiyonundan gelen değeri gözlemleyecek şekilde ayarlanmıştır. this anahtar kelimesini bu Observer’ın yaşam döngüsü sahibinin bu Activity olacağını bildirir.
public void onButtonClicked(View view) {
model.getCurrentDate().setValue(new Date().toString());
}
Burda butona basıldığında ise getCurrentDate() methodundan dönecek olan nesnesinin değerinin yeni tarih ile değiştirilmesi sağlanmıştır.
Peki DateViewModel sınıfımızın içeriği nasıl? Hemen inceleyelim.
DateViewModel sınıfımızda MutableLiveData isimli LiveData nın bir başka versiyonu kullanılmıştır. Bunun sebebi açık olarak setValue() ve getValue() fonksiyonlarının kullanılmak istenmesidir. Eğer bir LiveData üzerinde bu methodlar çağırılacak ise MutableLiveData kullanılmalıdır.
model.getCurrentDate().observe(this, dateObserver);
MainActivity içerisinde yukarıda yazılan komut ile getCurrentDate() den dönen değerin gözlemlenebilir olması sağlanmıştır.Peki bu gözlemlenebilir olma durumu nasıl sağlanmıştır? currentDate isimli LiveData nın null olup olmama durumuna göre tanımlama yapılıp geriye tekrar bu LiveData nesnesi döndürülürek bu nesnedeki değişiklerin gözlemlenebilir hale getirilmiştir.
Daha sonra ise her butana basıldığında loadCurrentDate() methodu çağırılarak currentDate isimli LiveData nın güncellenmesi sağlanmıştır. Aradaki bağlantı sayesinde ise her güncelleme otomatik olarak bildirilir ve kullanıcı arayüzüne yazdırılır.
Aşağıdaki görüntüde görüldüğü üzere tarih verisi konfigürasyon değişikliği olduğu zaman bile en son halini tutar. Her bir butona basıldığı anda ise ekrandaki veri otomatik olarak LiveData yı gözlemleyen Observer aracılığıyla gözlemlenir.
Bu yazımız da bitti. Bir sonraki yazımızda görüşmek dileğiyle
The more code the more happiness