Android dünyasına yeni adım atıyorsanız, sunum katmanında verileri nasıl ele alacağınız konusundaki sürekli sorunla mutlaka karşılaşmışsınızdır. Uzun süre LiveData en üstün çözümdü, ancak Kotlin coroutine'lerinin ortaya çıkmasıyla çok daha güçlü ve esnek araçlar gelişti. Bunlar, veri akışlarını reaktif ve verimli bir şekilde yönetmenin doğal evrimi olan StateFlow ve SharedFlow'dur .
Gerçek şu ki, ilk bakışta benzer kavramlar gibi görünseler de, her birinin kendi amacı var. Ekranın haber akışının nerede kaldığını hatırlamasını istemek, yalnızca bir kez görüntülenmesi gereken bir Toast bildirimi göndermek istemekle aynı şey değil. Karışıklığı önlemek için, bu sıcak akışların nasıl çalıştığını ve modern projelerinizde LiveData'yı neden geride bırakmayı düşünmeniz gerektiğini inceleyelim.
Akış kavramı: Soğuk mu, sıcak mı?
StateFlow ve SharedFlow'u anlamak için öncelikle soğuk ve sıcak akış arasındaki farkı kavramanız gerekir. Standart bir akış soğuktur , yani bir yemek tarifi gibidir: biri onu çalıştırmaya karar verene kadar (`collect` çağrısı yapana kadar) hiçbir şey olmaz. Sorun şu ki, üç aboneniz varsa, üreticinin kodu üç kez çalışır; bu da pili tüketebilir veya gereksiz API isteklerine neden olabilir.
İşte burada aktif akışlar devreye giriyor. Hem StateFlow hem de SharedFlow stratejik olarak aktif akışlardır ; yani üretici, dinleyen olup olmamasına bakılmaksızın aktif kalır. Bu, birden fazla toplayıcının aynı veri kaynağını paylaşmasına olanak tanır ve uygulamanın aynı işi tekrar tekrar yapmasını önler; bu da sistem akışkanlığını korumak için hayati önem taşır.
StateFlow: LiveData için ideal alternatif
StateFlow özünde bir durum kapsayıcısıdır. Ana özelliği, her zaman geçerli bir değeri koruması ve bu değerin `.value` özelliği kullanılarak eş zamanlı olarak sorgulanabilmesidir. Ekranın yüklenip yüklenmediği veya profil verilerinin başarıyla güncellenip güncellenmediği gibi kullanıcı arayüzünün durumunu yönetmek için mükemmel bir araçtır.
LiveData'nın aksine, StateFlow yapıcı fonksiyonunda bir başlangıç değeri gerektirir ve bu da başlangıçta boş durumların belirsizliğini ortadan kaldırır. Ayrıca, birleştirme ve tekilleştirme davranışını uygular : aynı değeri art arda iki kez gönderirseniz, akış bunu basitçe yok sayar. Bu, veriler aslında değişmediğinde kullanıcı arayüzünün gereksiz yere yenilenmesini önlemek için harika bir özelliktir.
Bunu bir ViewModel'de uygulamak için en iyi yaklaşım, özel bir MutableStateFlow yedek özelliği kullanmak ve bunu değiştirilemez bir StateFlow olarak sunmaktır. Bu, yalnızca ViewModel'in durumu değiştirebilmesini sağlar, tek yönlü veri akışına saygı duyar ve görünümün verileri manipüle etmesini engeller.
SharedFlow: Benzersiz eylemler için olay veri yolu
Eğer StateFlow "durum" içinse, SharedFlow "olaylar" içindir. Bir hata iletişim kutusu görüntülemek veya başka bir ekrana geçmek istediğinizi düşünün. StateFlow kullanıyorsanız, cihazı döndürmek yeni toplayıcının son değeri almasına ve olayın tekrar tetiklenmesine neden olur; bu ciddi bir hatadır. SharedFlow bunu çözer çünkü tekrar oynatma değeri sıfır olarak yapılandırılabilir.
Bu akış çok daha esnektir ve taşma tamponu gibi parametreleri ayarlamamıza olanak tanır . Tampon dolarsa, göndericiyi askıya almayı veya en eski veya en yeni değeri atmayı seçebiliriz. Önemli bir avantajı, SharedFlow'un tekrarlanan değerler göndermenize izin vermesidir ; aynı "Bağlantı Hatası" mesajını üç kez göndermeniz gerekiyorsa, SharedFlow bunu tereddüt etmeden yapacaktır, oysa StateFlow bunları filtreleyecektir.
Teknik karşılaştırma: StateFlow, SharedFlow ve LiveData
Teknik bir mülakatta veya mimarinizi tasarlarken karışıklığı önlemek için kritik noktaları göz önünde bulundurmak önemlidir. LiveData basittir ve yaşam döngüsünü otomatik olarak yönetir , ancak Android'e çok bağlıdır. Kotlin Coroutines'in bir parçası olan StateFlow ve SharedFlow ise platformdan bağımsızdır ; bu da birim testlerini ve temiz alan katmanlarının oluşturulmasını büyük ölçüde kolaylaştırır.
- Durum AkışıBaşlangıç değeri atar, .value özelliğine sahiptir, değerleri tekrarlardan arındırır ve kullanıcı arayüzü durumları için idealdir.
- Paylaşılan AkışBaşlangıç değeri gerektirmez, tekrar oynatma açısından yapılandırılabilir ve geçici olaylar için doğru seçenektir.
- Canlı veriBaşlangıç değerine ihtiyaç duymaz, yaşam döngüsünün farkındadır ancak eşzamansız dönüşümlerde daha az etkilidir.
Güvenli hasadın önemi
Sık yapılan bir hata, Activity içindeki basit bir coroutine kapsamı içinde `collect` çalıştırmaktır. Bu tehlikelidir çünkü uygulama arka planda çalışırken bile veri işleme devam eder ve bu da çökmelere veya aşırı CPU kullanımına neden olabilir. Modern çözüm , `repeatOnLifecycle(Lifecycle.State.STARTED)` API'sini kullanmaktır.
Bu fonksiyon, görünüm görünür olduğunda koleksiyonun etkinleşmesini ve STOPPED durumuna ulaştığında otomatik olarak iptal edilmesini sağlar. Jetpack Compose için, bu mantığı yerel olarak entegre eden ve uygulamanın cihaz kaynaklarını verimli kullanmasını sağlayan `collectAsStateWithLifecycle()` kullanılması önerilir .
Soğuk akımları sıcak akımlara dönüştürmek
Bazen veritabanından (Room gibi) veya depodan gelen ve soğuk olan bir akışımız olur. Bunu sıcak hale getirmek için `stateIn` veya `shareIn` operatörlerini kullanırız . Bu operatörler bir `CoroutineScope` ve bir başlatma stratejisi gerektirir. En yaygın olanı `SharingStarted.WhileSubscribed(5000)`' dir.
Bu yapılandırma mükemmel çünkü aboneler olduğu sürece akışı aktif tutuyor ve ekran kapatıldığında akışı durdurmadan önce 5 saniye bekliyor. Bu, ekran döndürme sırasında akışın yok edilip yeniden oluşturulmaması ve böylece sunucuya veya yerel veritabanına gereksiz isteklerin önlenmesi açısından çok önemlidir.
Bu araçlara hakim olmak, durumun StateFlow kullanılarak kalıcı ve yinelenmeyen bir şekilde yönetilmesi gerektiğini, tek seferlik işlemlerin ise SharedFlow üzerinden akması gerektiğini anlamayı gerektirir. Bunu yaşam döngüsü farkındalığı ve stateIn kullanarak soğuk akış dönüşümüyle birleştirerek, mobil cihazlarda gerçek dünya performansı için optimize edilmiş sağlam, tamamen reaktif bir Android mimarisi elde ederiz. Bu kılavuzu paylaşın ve başkalarının bu konu hakkında bilgi edinmesine yardımcı olun.
