Bu sayfada, bir bileşenin yaşam döngüsü ve Compose'un bir bileşenin yeniden derlenmesi gerekip gerekmediğine nasıl karar verdiği hakkında bilgi edineceksiniz.
Yaşam döngüsüne genel bakış
Durum yönetimi dokümanlarında belirtildiği gibi, kompozisyonlar uygulamanızın kullanıcı arayüzünü tanımlar ve derlenebilirler çalıştırılarak oluşturulur. Bir kompozisyon, kullanıcı arayüzünüzü tanımlayan bileşenlerin ağaç yapısıdır.
Jetpack Compose, ilk kompozisyon sırasında, kompozisyonlarda kullanıcı arayüzünüzü tanımlamak için çağırdığınız kompozisyonları izler. Ardından, uygulamanızın durumu değiştiğinde Jetpack Compose bir yeniden derleme planlar. Yeniden kompozisyon, Jetpack Compose'un durum değişikliklerine yanıt olarak değişmiş olabilecek kompozisyonları yeniden yürütmesi ve ardından kompozisyonu değişiklikleri yansıtacak şekilde güncellemesi işlemidir.
Bir kompozisyon yalnızca ilk kompozisyonla üretilebilir ve yeniden kompozisyon oluşturma işlemiyle güncellenebilir. Bir kompozisyonu değiştirmenin tek yolu yeniden kompozisyon oluşturmaktır.
Şekil 1. Kompozisyondaki bir bileşenin yaşam döngüsü. Parça, kompozisyona girer, 0 veya daha fazla kez yeniden derlenir ve kompozisyondan çıkar.
Yeniden oluşturma işlemi genellikle bir State<T>
nesnesinde yapılan bir değişiklik tarafından tetiklenir. Oluşturma, bu öğeleri izler ve kompozisyondaki belirli State<T>
öğesini okuyan tüm kompozisyon öğelerini ve bu öğelerin çağırdığı, atlanamayan tüm kompozisyon öğelerini çalıştırır.
Bir kompozisyon birden çok kez çağrılırsa kompozisyona birden çok örnek yerleştirilir. Her çağrının, kompozisyonda kendi yaşam döngüsü vardır.
@Composable fun MyComposable() { Column { Text("Hello") Text("World") } }
Şekil 2. Bileşimde MyComposable
'ün temsili. Bir derlenebilir öğe birden çok kez çağrılırsa kompozisyona birden çok örnek yerleştirilir. Farklı renkteki öğeler ayrı bir örnek olduğunu gösterir.
Kompozisyondaki bir bileşenin anatomisi
Kompozitte bir bileşenin örneği, çağrı sitesi ile tanımlanır. Oluşturma derleyicisi her çağrı sitesini ayrı olarak değerlendirir. Birden fazla çağrı sitesinden çağrılan bileşimler, bileşimin kompozisyonda birden fazla örneğini oluşturur.
Bir yeniden derleme sırasında bir derlenebilir, önceki derleme sırasında çağrılanlardan farklı derlenebilirler çağırırsa Derle, hangi derlenebilirlerin çağrıldığını veya çağrılmadığını belirler. Ayrıca, her iki derlemede de çağrılan derlenebilirler için girişleri değişmediyse bunları yeniden derlemekten kaçınır.
Yan etkileri, her yeniden derleme için yeniden başlatmak yerine başarıyla tamamlayabilmeleri amacıyla derlenebilir öğeleriyle ilişkilendirmek için kimliği korumak çok önemlidir.
Aşağıdaki örneği inceleyin:
@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
, LoginError
bileşenini koşullu olarak çağırır ve LoginInput
bileşenini her zaman çağırır. Her çağrının benzersiz bir çağrı yeri ve kaynak konumu vardır. Derleyici, çağrıyı benzersiz şekilde tanımlamak için bu konumları kullanır.
Şekil 3. Durum değiştiğinde ve yeniden kompozisyon oluştuğunda kompozisyondaki LoginScreen
temsili. Aynı renk, yeniden derlenmediği anlamına gelir.
LoginInput
önce çağrılırken şimdi ikinci çağrılmaya başlasa bile LoginInput
örneği yeniden derlemelerde korunur. Ayrıca, LoginInput
'te yeniden derleme sırasında değişen herhangi bir parametre olmadığından, LoginInput
çağrısı Derle tarafından atlanır.
Akıllı yeniden derlemelere yardımcı olmak için ek bilgi ekleme
Bir derlenebilir öğeyi birden çok kez çağırmak, öğeyi bestelemeye de birden çok kez ekler. Bir bileşeni aynı çağrı sitesinden birden çok kez çağırırken Compose, söz konusu bileşene yapılan her çağrıyı benzersiz şekilde tanımlayacak herhangi bir bilgiye sahip değildir. Bu nedenle, örnekleri birbirinden ayırmak için çağrı sitesine ek olarak yürütme sırası kullanılır. Bazen bu davranış yeterlidir ancak 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, Oluştur, örneğin Oluşturma işleminde farklı kalması için çağrı yerine yürütme sırasını kullanır. Listenin altına yeni bir movie
eklenirse Oluştur, listedeki konumları değişmediğinden ve bu nedenle movie
girişi bu örnekler için aynı olduğundan, Oluştur'da zaten bulunan örnekleri yeniden kullanabilir.
Şekil 4. Listenin en altına yeni bir öğe eklendiğinde kompozisyondaki MoviesScreen
temsili. Kompozisyondaki MovieOverview
bileşenleri yeniden kullanılabilir. MovieOverview
'te aynı renk, derlenebilir öğenin yeniden derlenmediği 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ş parametresi listedeki konumunu değiştiren tüm MovieOverview
çağrılarında yeniden derleme işlemi gerçekleşir. Örneğin, MovieOverview
bir yan etki kullanarak film resmi getiriyorsa bu son derece önemlidir. Yeniden derleme işlemi, efekt devam ederken gerçekleşirse iptal edilir ve yeniden başlar.
@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) /* ... */ } }
Şekil 5. Listeye yeni bir öğe eklendiğinde kompozisyondaki MoviesScreen
temsili. MovieOverview
bileşenleri yeniden kullanılamaz ve tüm yan etkiler yeniden başlar. MovieOverview
alanında farklı bir renk, derlenebilir öğenin yeniden derlendiği anlamına gelir.
İdeal olarak, MovieOverview
örneğinin kimliğini kendisine iletilen movie
örneğinin kimliğine bağlı olarak düşünmek isteriz. Film listesini yeniden sıralarsak ideal olarak her MovieOverview
kompozisyonunu farklı bir film örneğiyle yeniden oluşturmak yerine, kompozisyon ağacındaki örnekleri de benzer şekilde yeniden sıralamamız gerekir. Oluşturma, ağacın belirli bir bölümünü tanımlamak için hangi değerleri kullanmak istediğinizi çalışma zamanında belirtmenize olanak tanır: key
bileşeni.
Bir kod bloğunu, iletilen bir veya daha fazla değerle birleştirilebilir anahtar çağrısıyla sarmalayarak bu değerler birleştirilir ve kompozisyondaki ilgili örneği tanımlamak için kullanılır. key
değerinin global olarak benzersiz olması gerekmez. Yalnızca çağrı sitesindeki birleştirilebilir öğelerin çağrıları arasında benzersiz olması gerekir. Bu nedenle, bu örnekte her movie
'ün movies
arasında benzersiz bir key
'ye sahip olması gerekir. Bu key
'ü uygulamanın başka bir yerindeki başka bir kompozisyonla paylaşabilir.
@Composable fun MoviesScreenWithKey(movies: List<Movie>) { Column { for (movie in movies) { key(movie.id) { // Unique ID for this movie MovieOverview(movie) } } } }
Yukarıdaki yöntemle, listedeki öğeler değişse bile Oluştur, MovieOverview
çağrılarını tanır ve yeniden kullanabilir.
Şekil 6. Listeye yeni bir öğe eklendiğinde kompozisyondaki MoviesScreen
temsili. MovieOverview
bileşenleri benzersiz anahtarlara sahip olduğundan Compose, hangi MovieOverview
örneklerinin değişmediğini tanır ve bunları yeniden kullanabilir. Bu bileşenlerin yan etkilerinin yürütülmesi devam eder.
Bazı bileşenlerde key
bileşeni için yerleşik destek bulunur. Örneğin,
LazyColumn
, items
DSL'sinde ö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 atlama
Yeniden oluşturma sırasında, girişleri önceki bileşimden değişmemişse bazı uygun birleştirilebilir işlevlerin yürütülmesi tamamen atlanabilir.
Bir composable işlevi, aşağıdakiler hariç atlanabilir:
- İşlevin
Unit
olmayan bir dönüş türü var - İşlev,
@NonRestartableComposable
veya@NonSkippableComposable
ile ek açıklamaya sahiptir - Gerekli bir parametre kararlı olmayan bir türde
Son koşulu gevşeten deneysel bir derleyici modu olan Güçlü Atlama vardır.
Bir türün kararlı olarak kabul edilebilmesi için aşağıdaki sözleşmeye uyması gerekir:
- İki örnek için
equals
sonucu, aynı iki örnek için her zaman aynı olacaktır. - Bu türdeki herkese açık bir mülk değişirse kompozisyon bilgilendirilir.
- Tüm herkese açık mülk türleri de kararlıdır.
Bu sözleşmeye giren ve @Stable
ek açıklamasıyla açıkça kararlı olarak işaretlenmemesine rağmen Compose derleyicisinin kararlı olarak ele alacağı bazı önemli ortak türler vardır:
- Tüm ilkel değer türleri:
Boolean
,Int
,Long
,Float
,Char
vb. - Yaylı Çalgılar
- Tüm işlev türleri (lambdalar)
Bu türlerin tümü, sabit oldukları için kararlı sözleşmeyi uygulayabilir. Değişmez türler hiçbir zaman değişmediğinden, Composition'un değişikliği bildirmesi gerekmez. Bu nedenle, bu sözleşmeyi takip etmek çok daha kolaydır.
Sabit ancak değişken olan önemli türlerden biri, Compose'un MutableState
türüdür. Bir değer MutableState
içinde tutulursa State
öğesinin .value
mülkünde yapılan değişikliklerden Compose bilgilendirileceğinden durum nesnesi genel olarak kararlı kabul edilir.
Bir bileşene parametre olarak iletilen tüm türler kararlı olduğunda, parametre değerleri, kullanıcı arayüzü ağacındaki bileşen 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 atlanır.
Oluşturma, bir türün kararlı olduğunu yalnızca kanıtlayabiliyorsa kabul eder. Örneğin, bir arayüz genellikle kararlı olarak kabul edilmez ve uygulaması değişmez olabilecek, değiştirilebilir herkese açık özelliklere sahip türler de kararlı değildir.
Derleme, bir türün kararlı olduğunu anlayamıyorsa ancak Derleme'yi türünü kararlı olarak ele almaya zorlamak istiyorsanız türünü @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 değerlendirmeyebilir. @Stable
ek açıklamasını ekleyerek Compose'a bu türün kararlı olduğunu bildirirsiniz. Böylece Compose, akıllı yeniden derlemeleri tercih eder. 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
- Oluşturma bölümündeki yan etkiler
- Oluştur'da kullanıcı arayüzü durumunu kaydetme