Bu sayfada, bir composable'ın yaşam döngüsü ve Compose'un bir composable'ın yeniden oluşturulması gerekip gerekmediğine nasıl karar verdiği hakkında bilgi edineceksiniz.
Yaşam döngüsüne genel bakış
Durum yönetimi belgelerinde belirtildiği gibi, oluşturma işlemi uygulamanızın kullanıcı arayüzünü tanımlar ve composable'lar çalıştırılarak oluşturulur. Oluşturma, kullanıcı arayüzünüzü tanımlayan composable'ların ağaç yapısıdır.
Jetpack Compose, ilk oluşturma sırasında composable'larınızı ilk kez çalıştırdığında, kullanıcı arayüzünüzü bir oluşturmada tanımlamak için çağırdığınız composable'ları takip eder. Ardından, uygulamanızın durumu değiştiğinde Jetpack Compose bir yeniden oluşturma işlemi planlar. Yeniden oluşturma, Jetpack Compose'un durum değişikliklerine yanıt olarak değişmiş olabilecek composable'ları yeniden yürütmesi ve ardından değişiklikleri yansıtmak için oluşturmayı güncellemesidir.
Oluşturma işlemi yalnızca ilk oluşturma ile üretilebilir ve yeniden oluşturma ile güncellenebilir. Oluşturmayı değiştirmenin tek yolu yeniden oluşturmadır.
Yeniden oluşturma işlemi genellikle bir State<T> nesnesinde yapılan değişiklikle tetiklenir. Compose bunları takip eder ve oluşturmada söz konusu State<T> değerini okuyan tüm composable'ları ve bunların çağırdığı, atlanamayan tüm composable'ları çalıştırır.
Bir composable birden çok kez çağrılırsa oluşturmaya birden çok örnek yerleştirilir. Her çağrının, oluşturma işleminde kendi yaşam döngüsü vardır.
@Composable fun MyComposable() { Column { Text("Hello") Text("World") } }
MyComposable öğesinin oluşturmadaki temsili. Bir composable birden çok kez çağrılırsa oluşturmaya birden çok örnek yerleştirilir. Farklı renkteki öğeler, ayrı bir örnek olduğunu gösterir.Oluşturma işleminde bir composable'ın anatomisi
Oluşturma işlemindeki bir composable örneği, çağrı sitesi ile tanımlanır. Compose derleyicisi, her çağrı sitesini ayrı olarak değerlendirir. Oluşturulabilir öğeleri birden fazla çağrı sitesinden çağırmak, oluşturulabilir öğenin birden fazla örneğini oluşturur.
Yeniden oluşturma sırasında bir composable, önceki oluşturma sırasında çağırdığından farklı composable'lar çağırırsa Compose, hangi composable'ların çağrıldığını veya çağrılmadığını belirler. Her iki oluşturmada da çağrılan composable'lar için Compose, girişleri değişmediyse bunları yeniden oluşturmaz.
Kimliğin korunması, yan etkilerin kendi composable'larıyla ilişkilendirilmesi açısından çok önemlidir. Bu sayede, her yeniden oluşturma işleminde yeniden başlatılmak yerine başarıyla tamamlanabilirler.
Aşağıdaki örneği inceleyelim:
@Composable fun LoginScreen(showError: Boolean) { if (showError) { LoginError() } LoginInput() // This call site affects where LoginInput is placed in Composition } @Composable fun LoginInput() { /* ... */ } @Composable fun LoginError() { /* ... */ }
Yukarıdaki kod snippet'inde LoginScreen, koşullu olarak LoginError composable'ını ve her zaman LoginInput composable'ını çağırır. Her çağrının benzersiz bir çağrı sitesi ve kaynak konumu vardır. Derleyici, çağrıyı benzersiz şekilde tanımlamak için bunları kullanır.
LoginScreen öğesinin temsili. Aynı renk, yeniden oluşturulmadığı anlamına gelir.LoginInput ilk çağrılan öğe olmaktan çıkıp ikinci çağrılan öğe olsa da LoginInput örneği, yeniden oluşturma işlemleri boyunca korunur. Ayrıca LoginInput, yeniden oluşturma sırasında değişen parametrelere sahip olmadığından LoginInput çağrısı, Oluşturma tarafından atlanır.
Akıllı yeniden oluşturma işlemlerine yardımcı olacak ek bilgiler ekleme
Bir composable'ı birden çok kez çağırdığınızda, bu composable oluşturmaya da birden çok kez eklenir. Aynı çağrı sitesinden bir composable'ı birden çok kez çağırırken Compose, bu composable'a yapılan her çağrıyı benzersiz şekilde tanımlayacak herhangi bir bilgiye sahip değildir. Bu nedenle, örnekleri ayrı tutmak için çağrı sitesine ek olarak yürütme sırası kullanılır. Bazen bu davranış yeterli olsa da bazı durumlarda istenmeyen davranışlara neden olabilir.
@Composable fun MoviesScreen(movies: List<Movie>) { Column { for (movie in movies) { // MovieOverview composables are placed in Composition given its // index position in the for loop MovieOverview(movie) } } }
Yukarıdaki örnekte Compose, örneği oluşturmada ayrı tutmak için çağrı sitesine ek olarak yürütme sırasını kullanır. Listenin altına yeni bir movie eklenirse Compose, listedeki konumları değişmediği için oluşturmadaki mevcut örnekleri yeniden kullanabilir. Bu nedenle, movie girişi bu örnekler için aynıdır.
MoviesScreen öğesinin oluşturmadaki temsili. Oluşturma işlemindeki MovieOverview bileşenleri yeniden kullanılabilir. MovieOverview renginin aynı olması, composable'ın yeniden oluşturulmadığı anlamına gelir.Ancak movies listesi, listenin üstüne veya ortasına öğe eklenerek, öğeler kaldırılarak ya da yeniden sıralanarak değişirse giriş parametresinin listedeki konumu değişen tüm MovieOverview çağrılarında yeniden oluşturma işlemi gerçekleşir. Örneğin, MovieOverview bir yan etki kullanarak film resmi getiriyorsa bu son derece önemlidir. Efekt uygulanırken yeniden oluşturma işlemi gerçekleşirse efekt iptal edilir ve tekrar başlatılır.
@Composable fun MovieOverview(movie: Movie) { Column { // Side effect explained later in the docs. If MovieOverview // recomposes, while fetching the image is in progress, // it is cancelled and restarted. val image = loadNetworkImage(movie.url) MovieHeader(image) /* ... */ } }
MoviesScreen öğesinin oluşturmadaki temsili. MovieOverview bileşenleri yeniden kullanılamaz ve tüm yan etkiler yeniden başlatılır. MovieOverview içinde farklı bir renk, composable'ın yeniden oluşturulduğu anlamına gelir.İdeal olarak, MovieOverview örneğinin kimliğinin, kendisine iletilen movie kimliğine bağlı olduğunu düşünmek isteriz. Film listesini yeniden sıralarsak her MovieOverview composable'ı farklı bir film örneğiyle yeniden oluşturmak yerine, ideal olarak oluşturma ağacındaki örnekleri de benzer şekilde yeniden sıralarız. Compose, çalışma zamanına ağacın belirli bir bölümünü tanımlamak için hangi değerleri kullanmak istediğinizi belirtmenize olanak tanır: key bileşeni.
Bir kod bloğunu, bir veya daha fazla değer iletilen anahtar composable ile sarmalayarak bu değerler, oluşturmadaki bu örneği tanımlamak için kullanılmak üzere birleştirilir. key değeri genel olarak benzersiz olmak zorunda değildir. Yalnızca çağrı sitesindeki composable'ların çağrıları arasında benzersiz olması gerekir. Bu örnekte her movie, movies içinde benzersiz bir key değerine sahip olmalıdır. Bu key değerini uygulamanın başka bir yerindeki başka bir composable ile paylaşması sorun olmaz.
@Composable fun MoviesScreenWithKey(movies: List<Movie>) { Column { for (movie in movies) { key(movie.id) { // Unique ID for this movie MovieOverview(movie) } } } }
Yukarıdaki örnekte, listedeki öğeler değişse bile Compose, MovieOverview için yapılan ayrı ayrı çağrıları tanır ve bunları yeniden kullanabilir.
MoviesScreen öğesinin oluşturmadaki temsili. MovieOverview bileşenlerinin benzersiz anahtarları olduğundan, Compose hangi MovieOverview örneklerinin değişmediğini tanır ve bunları yeniden kullanabilir. Bu örneklerin yan etkileri yürütülmeye devam eder.Bazı composable'lar, key composable için yerleşik desteğe sahiptir. Örneğin,
LazyColumn, items DSL'de özel bir key belirtilmesini kabul eder.
@Composable fun MoviesScreenLazy(movies: List<Movie>) { LazyColumn { items(movies, key = { movie -> movie.id }) { movie -> MovieOverview(movie) } } }
Girişler değişmediyse atlanıyor
Yeniden oluşturma sırasında, girişleri önceki oluşturma işleminden bu yana değişmemişse uygun bazı composable işlevlerin yürütülmesi tamamen atlanabilir.
Aşağıdaki durumlar haricinde, composable işlevler atlanabilir:
- İşlevin dönüş türü
Unitdeğil - İşlev,
@NonRestartableComposableveya@NonSkippableComposableile ek açıklama eklenmiş. - Gerekli bir parametre, kararlı olmayan bir türde
Son koşulu esneten Güçlü Atlama adlı bir derleyici modu vardır.
Bir türün kararlı olarak kabul edilebilmesi için aşağıdaki sözleşmeye uyması gerekir:
- İki örnek için
equalssonucu, aynı iki örnek için her zaman aynı olacaktır. - Türün herkese açık bir özelliği değişirse oluşturma bilgilendirilir.
- Tüm herkese açık mülk türleri de kararlıdır.
Bu sözleşmeye giren ve Compose derleyicisinin, @Stable ek açıklaması kullanılarak açıkça kararlı olarak işaretlenmemiş olsalar bile kararlı olarak değerlendireceği bazı önemli yaygın türler vardır:
- Tüm temel değer türleri:
Boolean,Int,Long,Float,Charvb. - Yaylı çalgılar
- Tüm işlev türleri (lambda'lar)
Bu türlerin tümü, değişmez oldukları için kararlı sözleşmesine uyabilir. Değişmez türler hiçbir zaman değişmediğinden, değişikliği oluşturma işlemine bildirmeleri gerekmez. Bu nedenle, bu sözleşmeye uymak çok daha kolaydır.
Kararlı ancak değiştirilebilir olan önemli bir tür, Compose'un MutableState türüdür. Bir değer MutableState içinde tutuluyorsa Compose, State öğesinin .value özelliğinde yapılan değişikliklerden haberdar olacağı için durum nesnesi genel olarak kararlı kabul edilir.
Bir composable'a parametre olarak iletilen tüm türler kararlı olduğunda parametre değerleri, kullanıcı arayüzü ağacındaki composable konumuna göre eşitlik açısından karşılaştırılır. Önceki çağrıdan bu yana tüm değerler değişmediyse yeniden oluşturma işlemi atlanır.
Compose, bir türü yalnızca kanıtlayabiliyorsa kararlı olarak kabul eder. Örneğin, bir arayüz genellikle kararlı olarak kabul edilmez ve uygulaması sabit olabilecek, değiştirilebilir herkese açık özelliklere sahip türler de kararlı değildir.
Compose bir türün kararlı olduğunu anlayamıyorsa ancak Compose'u bu türü kararlı olarak değerlendirmeye zorlamak istiyorsanız türü @Stable ek açıklamasıyla işaretleyin.
// Marking the type as stable to favor skipping and smart recompositions. @Stable interface UiState<T : Result<T>> { val value: T? val exception: Throwable? val hasError: Boolean get() = exception != null }
Yukarıdaki kod snippet'inde UiState bir arayüz olduğundan Compose, normalde bu türü kararlı olarak kabul etmeyebilir. @Stable ek açıklamasını ekleyerek Compose'a bu türün kararlı olduğunu bildirirsiniz. Böylece Compose, akıllı yeniden oluşturma işlemlerini tercih edebilir. Bu, arayüz parametre türü olarak kullanılıyorsa Compose'un tüm uygulamalarını kararlı olarak değerlendireceği anlamına da gelir.
Sizin için önerilenler
- Not: JavaScript kapalıyken bağlantı metni gösterilir.
- State ve Jetpack Compose
- Compose'da yan etkiler
- Compose'da kullanıcı arayüzü durumunu kaydetme