Bu sayfada, bir bileşiğin yaşam döngüsü ve Compose'un bir bileşiğin 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. Beste, kullanıcı arayüzünüzü açıklayan composable'ların ağaç yapısıdır.
Jetpack Compose, composable'ınızı ilk kez çalıştırdığında, beste olduğunda, açıklamak için çağrıda bulunduğunuz composable'ların takibini yapacaktır. kullanıcı arayüzünüzle bağdaştırılabilir. Ardından, uygulamanızın durumu değiştiğinde Jetpack, Oluştur, bir yeniden beste planla. Yeniden besteleme, Jetpack Compose'da durum değişikliklerine yanıt olarak değişmiş olabilecek composable'ları yeniden yürütür, ve ardından Beste'yi değişiklikleri yansıtacak şekilde günceller.
Bir kompozisyon yalnızca ilk kompozisyonla üretilebilir ve yeniden kompozisyon oluşturma işlemiyle güncellenebilir. Bir besteyi değiştirmenin tek yolu yeniden bestelemektir.
Şekil 1. Bestedeki bir composable'ın 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. Bestedeki MyComposable
temsili. Bir derlenebilir öğe birden çok kez çağrılırsa kompozisyona birden çok örnek yerleştirilir. Bir öğenin farklı bir renge sahip olması, onun
ayrı bir örnek oluşturabilirsiniz.
Bestede bir composable'ın anatomisi
Kompozit oluşturmadaki bir bileşen örneği, çağrı sitesi ile tanımlanır. Oluşturma derleyicisi her çağrı sitesini ayrı olarak değerlendirir. composable'lara çağrı yapma birden çok çağrı sitesinden gelen, composable'ın birden fazla Beste.
Yeniden besteleme sırasında bir composable, çağrı yaptığından farklı composable'ları çağırıyorsa sırasında, Compose hangi composable'ın daha önce ve her ikisinde de çağrılan composable'lar için bestelemediğinde, Compose girişleri daha sonra değiştirildi.
Kimliği korumak, yan etkileri derleyicileriyle ilişkilendirmek için çok önemlidir. Böylece, her yeniden derleme için yeniden başlatılmak yerine başarılı bir şekilde tamamlanabilirler.
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
koşullu olarak
LoginError
composable, her zaman LoginInput
composable'ı ç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
ilk çağrılmadan ikinci olarak çağrılmaya geçse de
LoginInput
örneği, yeniden oluşturmalarda 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 bestelemeye yardımcı olmak için ek bilgi ekleyin
Bir derlenebilir öğeyi birden çok kez çağırmak, öğeyi kompozisyona da 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, Compose,
site etiketini kullanabilirsiniz. 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. MovieOverview
composable
Beste 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. Bu, örneğin, MovieOverview
bir
film resmi oluştururum. Efekt açıkken yeniden oluşturma gerçekleşirse
iptal edilir ve baştan 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) /* ... */ } }
Şekil 5. Yeni bir yorum yazıldığında bestede MoviesScreen
öğesi listeye eklenir. MovieOverview
composable yeniden kullanılamaz ve
tekrar başlar. MovieOverview
içinde farklı bir renk,
composable yeniden derlendi.
İdeal olarak, MovieOverview
örneğinin kimliğini
kendisine aktarılan movie
kimliğinin kimliğine bağlıdır. Yeniden sipariş verirsek
oluşturursak benzer şekilde örnek film listesindeki örnekleri de
Her MovieOverview
composable'ı bir
örneği olabilir. 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 şu olması gerekmez:
global olarak benzersiz olması koşuluyla,
composable'ları kullanıma sunduk. 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. Yeni bir yorum yazıldığında bestede MoviesScreen
öğesi listeye eklenir. MovieOverview
bileşenlerinin benzersiz anahtarları 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ı composable'lar yerleşik key
composable desteğine sahiptir. Ö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:
- İşlev,
Unit
dışında bir dönüş türü içeriyor - İşlev,
@NonRestartableComposable
veya@NonSkippableComposable
- Gerekli parametrelerden biri kararsız 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, sonsuza dek anlamına gelir. - 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şme kapsamında yer alan ve müşterilerin
Compose derleyici, açık bir şekilde kullanılmasa bile kararlı olarak davranır
@Stable
ek açıklaması kullanılarak kararlı olarak işaretlendi:
- Tüm temel değer türleri:
Boolean
,Int
,Long
,Float
,Char
vb. - Yaylı Çalgılar
- Tüm işlev türleri (lambdalar)
Bu türlerin hepsi kararlı bir sözleşmedir çünkü hiçbir şey değişmez. Sabit türler hiçbir zaman değişmediğinden, Değişimin oluşumu; bu nedenle bu sözleşmeye uymak çok daha kolaydır.
Sabit ancak değişken olan önemli bir tür, Compose'un MutableState
türüdür. Bir değer MutableState
içinde tutulursa durum nesnesi genel olarak
Compose'un
State
öğesinin .value
özelliği.
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.
Compose, bir türün kararlı olduğu sonucunu çıkaramazsa ancak
Sabit olarak ele almak için ileti oluştur,
@Stable
ek açıklaması.
// 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ün kararlı olmadığını düşünebilir. @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, aynı zamanda Compose'un tüm
olarak kullanılabilmesini sağlar.
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