Bestelerin yaşam döngüsü

Bu sayfada, bir composable’ın yaşam döngüsünü ve Compose'un bir composable'ın yeniden bestelenmesinin gerekip gerekmediğini belirleme yöntemi.

Yaşam döngüsüne genel bakış

Eyalet yönetimi belgelerinde belirtildiği gibi, Beste, uygulamanızın kullanıcı arayüzünü açıklar ve composable'ların çalıştırılmasıyla üretilir. 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 Beste yalnızca başlangıçtaki bir besteyle üretilebilir ve güncellenebilir: bile olabilir. Bir besteyi değiştirmenin tek yolu yeniden bestelemektir.

Bir composable'ın yaşam döngüsünü gösteren şema

Şekil 1. Bestedeki bir composable'ın yaşam döngüsü. Giriş Beste, 0 veya daha fazla kez yeniden bestelenir ve Beste'den çıkar.

Yeniden oluşturma, genellikle State<T> nesnesini tanımlayın. Oluştur bestedeki bu parçayı okuyan tüm composable'ları özel State<T> ve çağrıldıkları ancak tanımlanamayacak composable'lar atlandı.

Bir composable birden fazla kez çağrılırsa birden fazla örneği Beste. Bestede her çağrının kendi yaşam döngüsü vardır.

@Composable
fun MyComposable() {
    Column {
        Text("Hello")
        Text("World")
    }
}

Önceki kod snippet&#39;inde bulunan öğelerin hiyerarşik düzenini gösteren şema

Şekil 2. Bestedeki MyComposable temsili. composable birden çok kez çağrılır, birden fazla örnek Beste. Bir öğenin farklı bir renge sahip olması, onun ayrı bir örnek oluşturabilirsiniz.

Bestede bir composable'ın anatomisi

Bestedeki bir composable, çağrı sitesi tarafından tanımlanır. Compose 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 Compose, yaptığınız composable'ın hangi composable'ın 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 composable ile ilişkilendirmek açısından çok önemlidir. her bir görev için yeniden başlatmak yerine başarılı bir şekilde bile olabilir.

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 biri çağrısının, derleyicinin kullanacağı benzersiz bir çağrı sitesi ve kaynak konumu vardır: benzersiz bir şekilde tanımlamalısınız.

showError işaretinin true olarak değiştirilmesi durumunda önceki kodun nasıl yeniden oluşturulduğunu gösteren şema. LoginError composable eklenir ancak diğer composable&#39;lar yeniden derlenmez.

Şekil 3. Eyalet olduğunda bestede LoginScreen temsili ve yeniden oluşturma gerçekleşiyor. Aynı renk yeniden düzenlenmediğ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, çünkü LoginInput, reklam öğeleri genelinde değişen herhangi bir parametreye sahip yeniden düzenleme, LoginInput çağrısı Compose tarafından atlanır.

Akıllı yeniden bestelemeye yardımcı olmak için ek bilgi ekleyin

Bir composable'ı birden fazla kez çağırmak, bu composable'ın Beste'ye birden fazla kez eklenmesini sağlar. olur. Bir composable'ı aynı çağrı sitesinden birden çok kez çağırdığınızda, Oluştur composable'a yapılan her çağrıyı benzersiz şekilde tanımlayacak herhangi bir bilgiye sahip değilse, Bu nedenle, sürecin en iyi uygulamalara devam etmesini sağlamak için sağlar. Bazen tüm gereken bu davranış 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, site etiketini kullanabilirsiniz. Yeni bir movie eklenirse listenin altına bastığınızda, Compose'da zaten bulunan Listedeki konumundan bu yana olan bileşim değişmemiştir. Bu nedenle, movie girişi bu örnekler için aynı.

Listenin sonuna yeni bir öğe eklenmesi durumunda önceki kodun nasıl yeniden oluşturulduğunu gösteren şema. Listedeki diğer öğelerin konumu değişmedi ve öğeler yeniden oluşturulmadı.

4.Şekil Yeni bir yorum yazıldığında bestede MoviesScreen öğesi, listenin en altına eklenir. MovieOverview composable Beste yeniden kullanılabilir. MovieOverview dilindeki aynı renk, composable anlamına gelir yeniden düzenlenmedi.

Ancak movies listesi en üste veya listenin ortasında yer alırsanız öğelerin kaldırılması veya sıralanması, yeniden oluşturma işlemine neden olur giriş parametresiMovieOverview liste'ye dokunun. 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)

        /* ... */
    }
}

Listenin başına yeni bir öğe eklenmesi durumunda önceki kodun nasıl yeniden oluşturulduğunu gösteren şema. Listedeki diğer tüm öğelerin konumu değişir ve öğenin yeniden oluşturulması gerekir.

5. Şekil. 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ştur, çalışma zamanına bildirmenin bir yolunu sunar. ağacın belirli bir bölümünü tanımlamak için kullanmak istediğiniz değerler: key composable'dan bahsetmek istiyorum.

Bir kod blokunu, composable anahtar için bir veya daha fazla komutla sarmalayarak bu değerler, ilgili verileri tanımlamak için örneğidir. key değerinin şu olması gerekmez: global olarak benzersiz olması koşuluyla, composable'ları kullanıma sunduk. Bu örnekte, her movie için bir movies arasında benzersiz olan key; o key öğesini uygulamanın başka bir yerinde composable,

@Composable
fun MoviesScreenWithKey(movies: List<Movie>) {
    Column {
        for (movie in movies) {
            key(movie.id) { // Unique ID for this movie
                MovieOverview(movie)
            }
        }
    }
}

Yukarıdaki işlemlerde, listedeki öğeler değişse bile Compose, aşağıdaki gibi MovieOverview için ayrı çağrı yapabilir ve bunları yeniden kullanabilir.

Listenin başına yeni bir öğe eklenmesi durumunda önceki kodun nasıl yeniden oluşturulduğunu gösteren şema. Liste öğeleri anahtarlarla tanımlandığı için, konumları değişse bile Compose bunları yeniden oluşturmayacağını bilir.

6. Şekil. Yeni bir yorum yazıldığında bestede MoviesScreen öğesi listeye eklenir. MovieOverview composable'ları benzersiz tuşlarını kullanarak, Compose hangi MovieOverview örneğin değişmediğini tanır ve yeniden kullanabilecekleri; devam eder.

Bazı composable'lar yerleşik key composable desteğine 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 atlama

Yeniden oluşturma sırasında bazı uygun composable işlevleri girişleri öncekine göre değişmemişse yürütme işlemi tamamen atlanır. bileşimi.

Bir composable işlev, aşağıdaki durumlar haricinde atlanmaya uygundur:

  • İşlev, Unit dışında bir dönüş türü içeriyor
  • İşlev, @NonRestartableComposable veya @NonSkippableComposable
  • Gerekli parametrelerden biri kararsız türde

Güçlü Atlama adlı deneysel bir derleyici modu vardır. Bu da son şartı gevşetiyor.

Bir türün kararlı olarak kabul edilmesi için aşağıdakilere uygun olması gerekir: sözleşme:

  • İki örnek için equals sonucu, sonsuza dek anlamına gelir.
  • Türün herkese açık bir mülkü değişirse Beste bilgilendirilir.
  • Tüm kamu mülkü türleri de sabittir.

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 (lambdas)

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 olan ancak değişebilen önemli bir tür, Compose'un MutableState öğesidir türü. Bir değer MutableState içinde tutulursa durum nesnesi genel olarak Compose'un State öğesinin .value özelliği.

Bir composable'a parametre olarak iletilen tüm türler kararlı olduğunda parametre, değerler, kullanıcı arayüzündeki composable konumuna göre eşitlik için karşılaştırılır ağacı. önceki çağrıya dokunun.

Compose, bir türü kanıtlayabildiği takdirde kararlı olarak kabul eder. Örneğin, arayüzün sabit olmadığı kabul edilir ve herkese açık türü değişken olan türler uygulaması sabit olabilen mülkler de kararlı değildir.

Compose, bir türün kararlı olduğu sonucunu çıkaramazsa ancak Sabit olarak ele almak için 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 genellikle bu türün sabit olmadığını düşünürüz. @Stable ekleyerek ek açıklama ile birlikte, Compose'a bu türün sabit olduğunu bildirerek Compose'un akıllı yeniden besteler. Bu, aynı zamanda Compose'un tüm olarak kullanılabilmesini sağlar.

ziyaret edin.