Jetpack Compose’ da Side-Effects: Uygulamanızı Etkileşimli Hale Getirin

Kerim Bora
8 min readApr 3, 2023

Android uygulamaları için kullanılan Jetpack Compose, uygulama geliştiricilerine modern, etkileşimli ve güçlü arayüzler oluşturma imkanı sunan yeni bir yaklaşım olarak öne çıkıyor. Bu yaklaşımın temel bileşenlerinden biri olan Side-Effects konusu ise, uygulamanın performansı, kullanılabilirliği ve etkileşimliliği açısından son derece önemli bir yere sahip. Bu yazıda, Jetpack Compose’ da Side-Effects konusunu ele alacak ve uygulamanızı daha etkileşimli hale getirmek için nasıl kullanabileceğinizi inceleyeceğiz.

Side-Effects Nedir?

Side-Effects, bir fonksiyonun dış dünya ile etkileşimini ifade eder. Bir fonksiyonun yan etkileri, fonksiyonun çalışması sırasında dışarıya veri yazması, okuması, dosya okuma/yazma, ağ istekleri yapma veya veritabanı işlemleri yapması gibi işlemleri kapsar.

Jetpack Compose’ da Side-Effects, uygulama içerisindeki işlevselliği arttırmak için kullanılır. Örneğin, bir kullanıcının bir butona tıkladığında, bir API isteği gönderilmesi gerekiyorsa, bu işlem Side-Effect olarak kabul edilir. Benzer şekilde, bir animasyon oynatmak, bir dosya okumak veya yazmak, bir veri tabanı işlemi yapmak gibi işlemler de Side-Effect olarak kabul edilir.

Side-Effects, Jetpack Compose uygulamalarında önemli bir role sahiptir, çünkü Composable fonksiyonlarının pure olması beklenir, yani fonksiyonların girdilerine göre her zaman aynı çıktıyı vermesi gerekmektedir. Bu nedenle, Composable fonksiyonlarında yan etkilerin (Side-Effects) yönetimi, uygulamanın doğru çalışması için son derece önemlidir.

Side-Effects’ in doğru bir şekilde yönetilmesi, uygulamanın performansı, kullanılabilirliği ve etkileşimliliği açısından son derece önemlidir. Özellikle, yanlış kullanılan Side-Effects, uygulamanın performansını düşürebilir veya beklenmeyen sonuçlar doğurabilir. Bu nedenle, Jetpack Compose’ da Side-Effects kullanmadan önce iyi bir planlama yapmak ve Side-Effects’ i doğru bir şekilde yönetmek, uygulamanın doğru çalışması için son derece önemlidir.

Jetpack Compose’ da Side-Effects Kullanmanın Faydaları

  1. Performans Artışı Jetpack Compose’ da Side-Effects, uygulamanın performansını artırabilir. Özellikle, Composable fonksiyonları sadece belirli koşullar altında yeniden hesaplamak için kullanılır. Bu nedenle, yanlış kullanılmadığı sürece, Side-Effects’ in performans üzerinde olumsuz bir etkisi olmaz.
  2. Daha Az Kodlama Jetpack Compose’ da Side-Effects kullanmak, geleneksel Android ara yüz kitaplıklarında olduğu gibi tekrarlayan kodların yazılmasını azaltabilir. Bu sayede, uygulamanın bakımı ve geliştirilmesi daha kolay hale gelir.
  3. Daha Az Hata Side-Effects, uygulamanın verimli çalışmasını sağlamak için önemlidir. Jetpack Compose’ da Side-Effects kullanmak, uygulamanın daha az hatayla çalışmasını sağlar. Ayrıca, Jetpack Compose daki Side-Effects yönetim mekanizmaları sayesinde, hatalar daha hızlı tespit edilip çözülebilir.
  4. Daha iyi Kullanılabilirlik Jetpack Compose’ da Side-Effects kullanmak, uygulamanın daha iyi kullanılabilir olmasını sağlar. Örneğin, bir animasyon veya özel bir efekt kullanarak kullanıcı etkileşimlerini artırabilirsiniz. Böylece, kullanıcılar uygulamanızı daha keyifli ve etkileşimli hale getirir.
  5. Daha iyi Ölçeklenebilirlik Jetpack Compose’ da Side-Effects kullanmak, uygulamanın daha iyi ölçeklenebilir olmasını sağlar. Özellikle, uygulamanın büyümesi ve daha fazla kullanıcının eşzamanlı kullanımı durumunda, Side-Effects’ in doğru bir şekilde yönetilmesi, uygulamanın ölçeklenebilirliğini artırır.

Jetpack Compose’ da Side-Effects Kullanma

Jetpack Compose’ da Side-Effects kullanmak oldukça kolaydır. İşte Jetpack Compose’ da Side-Effects kullanmak için birkaç yöntem:

  1. Side-Effect Kullanarak State Değiştirme State, Jetpack Compose’ da uygulama durumunu tutmak için kullanılan bir mekanizmadır. State, değiştiğinde uygulama otomatik olarak yenilenir ve ekrana yeni veriler yansıtılır. Bu olaya Re-Composition denir. Bir Side-Effect, uygulama durumunu değiştiren bir işlemi yürütmek için kullanılabilir. Örneğin, bir butona tıklandığında bir state’ i değiştirmek, Side-Effect kullanarak yapılabilir.
  2. LaunchedEffect Kullanarak Side-Effect Başlatma LaunchedEffect, bir Side-Effect’i çalıştırmak ve sonucunu bir state içinde depolamak için kullanılır. Örneğin, bir API isteği göndermek ve sonucunu bir state içinde saklamak için LaunchedEffect kullanılabilir.
  3. DisposableEffect Kullanarak Side-Effect’ i Yönetme DisposableEffect, bir Side-Effect’i yürütmek ve sonlandırmak için kullanılır. Örneğin, bir animasyonu başlatmak ve sonlandırmak için DisposableEffect kullanılabilir.

Jetpack Compose’da Side-Effects kullanırken, yan etkilerin uygulama durumunu nasıl etkilediğini anlamak önemlidir. Ayrıca, Side-Effects’in yürütülme sırasını ve sırasızlığını yönetmek de önemlidir. Bu nedenle, Jetpack Compose’ da Side-Effects kullanmadan önce iyi bir planlama yapmak ve Side-Effects’ i doğru bir şekilde yönetmek, uygulamanızın doğru çalışması için son derece önemlidir.

Jetpack Compose’ da kullanılan Side-Effect’ler, farklı işlevleri yerine getirebilirler ve farklı senaryolara uygunluk gösterebilirler. İşte Jetpack Compose’ da kullanılan Side-Effect çeşitleri ve uygulama yöntemleri:

  • LaunchedEffect
  • DisposableEffect
  • rememberCoroutineScope
  • produceState
  • rememberUpdateState

LaunchEffect Nedir ?

Jetpack Compose’ da LaunchEffect, bir CoroutineScope içinde çalışan bir işlemdir ve genellikle bir arayüz öğesi yüklenirken veya bir tıklama işlemi sırasında bir arka plan işlemi yapmak için kullanılır.

LaunchEffect, aşağıdaki şekilde kullanılabilir:

@Composable
fun MyComposable() {

LaunchedEffect(Unit) {
// background operation goes here
delay(5000) // simulate some background work
println("Background work completed!")
}

// Composable UI code goes here
// ...
}

LaunchedEffect fonksiyonu, bir işlemi başlatmak için kullanılır ve bu işlem bir, iki veya üç parametre alabilir. Bu parametreler, LaunchedEffect fonksiyonu tarafından takip edilir ve parametrelerin herhangi birisinin değeri değiştiğinde, işlem(coroutine) yeniden başlatılır ve Recomposition işlemi gerçekleşir.

Ancak, LaunchedEffect fonksiyonu, parametre olarak bir değer almak zorunda değildir. Bu durumda, fonksiyon Unit parametresi alır. Yani LaunchedEffect(Unit) { ... } şeklinde kullanılır. Bu, işlemin bir değeri takip etmesi gerekmeyen durumlarda kullanılabilir.

Örneğin, aşağıdaki gibi bir kullanımda, count değeri her değiştiğinde bir işlem yeniden başlatılır:

@Composable
fun MyComposition() {

var count: Int by remember { mutableStateOf(0) }

LaunchedEffect(count) {
println("count is $count")
}

Column {
Text(text = "Hello World!")
Text(text = "Count: $count")
Button(onClick = { count++ }) {
Text(text = "Increment")
}
}
}

LaunchedEffect fonksiyonu, count değeri değiştiğinde otomatik olarak tetiklenen bir yan etkidir(side effect) ve basitçe, her count değiştiğinde konsola "count is $count" şeklinde bir mesaj yazdırır.

DisposableEffect Nedir ?

DisposableEffect fonksiyonu, Jetpack Compose' da bir Composable' in oluşturulması veya yeniden oluşturulması sırasında, bir kaynağı almak ve kaynağı kullanım sonrası serbest bırakmak için kullanılır. Bu fonksiyon, Composable kaldırıldığında veya yeniden oluşturulduğunda kaynakları serbest bırakmak için kullanılabilir.

Örneğin, bir DisposableEffect ile bir önbellekten bir kaynağı almak ve bu kaynağı kullanımdan kaldırma örneği aşağıdaki gibi olabilir:

@Composable
fun MyComposable() {
var data by remember { mutableStateOf("") }
DisposableEffect(Unit) {
val cachedData = Cache.get()
if (cachedData != null) {
data = cachedData
}
onDispose {
// Clean up the resource
Cache.put(data)
}
}
// UI code that uses the data goes here
// ...
}

Bu örnekte, DisposableEffect kullanarak önbellekten cachedData adlı kaynağı alırız. cachedData değeri varsa, data'ya atarız. Sonra, onDispose bloğunu kullanarak, data'yı tekrar önbelleğe kaydederiz. Bu, Composable kaldırıldığında veya yeniden oluşturulduğunda otomatik olarak gerçekleştirilir.

rememberCoroutineScope Nedir?

rememberCoroutineScope fonksiyonu, Jetpack Compose'da bir Composable içinde coroutine kullanmak için kullanılır. Bu fonksiyon, Composable' in yaşam döngüsü boyunca aynı CoroutineScope' u yeniden kullanarak, Composable' in ömrü boyunca sıralı ve koordineli işlemler gerçekleştirmemizi sağlar.

Coroutine’ ler hakkında daha fazla bilgi sahibi olmak için aşağıdaki yazıma göz atabilirsiniz.

Örneğin, bir rememberCoroutineScope kullanarak, bir Composable' in içerisinde Snackbar gösterimi:

@Composable
fun MoviesScreen(snackbarHostState: SnackbarHostState) {

// Creates a CoroutineScope bound to the MoviesScreen's lifecycle
val scope = rememberCoroutineScope()

Scaffold(
snackbarHost = {
SnackbarHost(hostState = snackbarHostState)
}
) { contentPadding ->
Column(Modifier.padding(contentPadding)) {
Button(
onClick = {
// Create a new coroutine in the event handler to show a snackbar
scope.launch {
snackbarHostState.showSnackbar("Something happened!")
}
}
) {
Text("Press me")
}
}
}
}

produceState Nedir ?

produceState fonksiyonu, Jetpack Compose' da bir Composable içinde state' leri oluşturmak için kullanılır. Bu fonksiyon, bir state değiştiğinde, Composable' i otomatik olarak yeniler ve güncel state' i kullanır. Böylece, state' i takip etmek için ekstra bir kod yazmamıza gerek kalmaz.

mutableStateOf, Jetpack Compose'da bir state değişkeni oluşturmak için kullanılan bir fonksiyondur ve state'i oluştururken başlangıç değerini veririz. State değiştiğinde, state değişkeninin yeni değeri otomatik olarak kullanılır ve Composable yeniden oluşturulur.

produceState ise, Jetpack Compose'da bir Composable'in state'ini otomatik olarak güncellemesi için kullanılan bir fonksiyondur. produceState, state'in başlangıç değerini ve bir suspend fonksiyonu alır. suspend fonksiyonu, state'in güncellenmesi gerektiği zamanlarda çalıştırılabilir. Örneğin, bir API'den veri çekerken veya veri kaynağından veri alırken.

Temel fark, mutableStateOf sadece state değiştiğinde yenilenirken, produceState bir state değiştiğinde otomatik olarak yenilenir ve state değişikliklerini takip etmek için ekstra bir kod yazmamız gerekmez. Ancak, produceState daha fazla kodlama gerektirir ve suspend fonksiyonları kullanır. Bu nedenle, basit senaryolarda mutableStateOf kullanmak daha uygun olabilir, ancak karmaşık senaryolarda produceState daha faydalı olabilir.

Örneğin, bir produceState kullanarak, bir Composable' in state'ini bir veri kaynağından alabilir ve değişiklikleri takip edebiliriz. Örnek aşağıdaki gibi olabilir:

@Composable
fun MyComposition() {

var isLoading: Boolean by remember { mutableStateOf(true) }
val data: String by produceState(initialValue = ""){
value = getData()
isLoading = false
}

if (isLoading) {
CircularProgressIndicator()
} else {
Text(text = data)
}

}

suspend fun getData(): String {
delay(2000) // simulate a long-running operation
return "Data loaded from a data source"
}

Kod, bir MyComposition fonksiyonu içinde yazılmıştır ve bir değişken olan isLoading ve bir veri parçası olan data tanımlar. isLoading, remember ve mutableStateOf kullanılarak bir booleandır ve varsayılan olarak true olarak ayarlanır. data ise, produceState kullanılarak bir String olarak tanımlanır ve başlangıç değeri boş bir dize olarak atanır.

getData() fonksiyonu, suspend kullanarak asenkron bir işlem simüle eder ve 2 saniye boyunca bekler. Bu süre boyunca, uygulama yüklenme durumunda kalır.

MyComposition fonksiyonu, isLoading durumu true olduğu sürece CircularProgressIndicator() gösterir. Veriler yüklenip isLoading durumu false olduğunda, Text() widget 'ı gerçek verileri gösterir. data değişkeni, produceState tarafından otomatik olarak yenilendiği için, veriler yüklendiğinde Text() widget 'ı otomatik olarak güncellenir.

rememberUpdateState Nedir ?

rememberUpdatedState, Jetpack Compose'da bir Composable'in state'ini güncellemek için kullanılan bir fonksiyondur. Bu fonksiyon, Composable'in içindeki bir değeri güncellemeden önce, o değerin son bilinen değeri ile karşılaştırır. Eğer son bilinen değer, o değerin mevcut değerinden farklı ise, rememberUpdatedState yeni bir state döndürür ve Composable yeniden oluşturulur.

@Composable
fun LandingScreen(onTimeout: () -> Unit) {

// This will always refer to the latest onTimeout function that
// LandingScreen was recomposed with
val currentOnTimeout by rememberUpdatedState(onTimeout)

// Create an effect that matches the lifecycle of LandingScreen.
// If LandingScreen recomposes, the delay shouldn't start again.
LaunchedEffect(true) {
delay(SplashWaitTimeMillis)
currentOnTimeout()
}

/* Landing screen content */
}

rememberUpdatedState özelliği, onTimeout fonksiyonunun her güncellendiğinde en son sürümüne erişmemizi sağlar. LaunchedEffect özelliği, LandingScreen'in yaşam döngüsüne eşleşen bir etki yaratır. Bu etki, SplashWaitTimeMillis süre boyunca bekler ve daha sonra currentOnTimeout fonksiyonunu çağırır.

Özetle, rememberUpdatedState ve LaunchedEffect özellikleri, bir bileşenin(composable) güncellenmesi durumunda, önceki durumların korunmasını ve bileşenin beklenmeyen şekilde yeniden başlatılmamasını sağlamak için Jetpack Compose' da kullanılır.

Jetpack Compose daha yeni olduğu için yukarıda bahsettiğimiz event handler’ lar değişebilir. Daha fazla detay ve güncel doküman için Android Developer’ ı ziyaret edin.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Responses (1)

Write a response