Compose'da yığın izleme

Jetpack Compose, kodunuzu birden fazla farklı aşamada yürütür. Bu da @Composable işlevinin bazı bölümlerinin birbirinden ayrı olarak yürütülmesine neden olur. Bu aşamalarda meydana gelen kilitlenmeler, çözülmesi zor yığın izlemelere (stack trace) neden olabilir. Bu da kilitlenmeye neden olan tam işlevi veya kod satırını belirlemeyi zorlaştırır.

Yığın izlemelere kaynak bilgisi ekleme

Yığın izleme okunabilirliğini iyileştirmek için, isteğe bağlı bir API, composable adlar ve konumlar da dahil olmak üzere daha zengin kilitlenme konumu ayrıntıları sağlar. Bu sayede şunları yapabilirsiniz:

  • Kilitlenme kaynaklarını verimli bir şekilde belirleyip çözme
  • Yeniden oluşturulabilir örnekler için kilitlenmeleri izole etme
  • Daha önce yalnızca dahili yığın çerçevelerini gösteren kilitlenmeleri inceleme

Compose çalışma zamanı, oluşturma işlemindeki kilitlenme konumunu algılayabilir ve @Composable hiyerarşinize göre bir yığın izleme (stack trace) yeniden oluşturabilir. Yığın izleme, aşağıdaki durumlarda oluşan kilitlenmelere eklenir:

  • Beste
  • DisposableEffect ve LaunchedEffect (onDispose veya iptal hariç)
  • rememberCoroutineScope içinde başlatılan eş yordamlar
  • Ölçme, düzenleme ve çizme aşamaları

Bu özelliği etkinleştirmek için uygulama giriş noktasına aşağıdaki satırları ekleyin:

// Enable stack traces at application level: onCreate
class SampleStackTracesEnabledApp : Application() {

    override fun onCreate() {
        super.onCreate()
        // Enable Compose stack traces for minified builds only.
        Composer.setDiagnosticStackTraceMode(ComposeStackTraceMode.Auto)

        // Alternatively:
        // Enable verbose Compose stack traces for local debugging
        Composer.setDiagnosticStackTraceMode(ComposeStackTraceMode.SourceInformation)
    }
}

Yığın izleme bilgilerinin doğru şekilde toplandığını doğrulamak için bu yapılandırmayı herhangi bir oluşturma işlemi yapmadan önce gerçekleştirmeniz önerilir.

ComposeStackTraceMode için dört seçenek vardır:

  • Auto: Uygulama sadeleştirilmişse GroupKeys, aksi takdirde None kullandığı için önerilen seçenektir.
  • GroupKeys: Sadeleştirilmiş uygulamalar için yığın izlemeler oluşturulur. Grup anahtarı bilgileri, sadeleştirme işleminden sonra bile saklanır ve @Composable işlevlerinin yaklaşık konumunu yeniden oluşturmak için Compose derleyicisi ve R8 tarafından oluşturulan ProGuard eşleme dosyasıyla birlikte kullanılır. Bu yığın izlemeler daha az hassastır ve çalışma zamanında ek işlem yapmaktan kaçınacak şekilde optimize edilmiştir. Oluşturma derleyicisi, Kotlin 2.3.0'dan itibaren ek R8 eşlemelerinin yayınlanmasını destekler.
  • SourceInformation: Sadeleştirilmemiş derlemeler için kullanışlıdır. Kaynak bilgilerini toplar ve yığın izlemeye ekler. Sonuçlar daha doğru olsa da Layout Inspector'ı eklemeye benzer şekilde önemli bir performans maliyetine neden olur. Bu dosyalar, konumu hakkında daha fazla bilgi gerektiren kilitlenmelerle ilgili doğru ölçümler almak için uygulamaların hata ayıklama sürümlerinde kullanılmak üzere oluşturulur. İkili program boyutunu ve performansı optimize etmek için kaynak bilgileri, sadeleştirilmiş uygulamalardan kaldırılır.
  • None: Ek yığın izleme ayrıntısı eklenmez.

SourceInformation seçeneği kullanıldığında yığın izleme, bastırılmış istisna listesinde DiagnosticComposeException olarak görünür:

java.lang.IllegalStateException: Test layout error
    at <original trace>
Suppressed: androidx.compose.runtime.DiagnosticComposeException:
Composition stack when thrown:
    at ReusableComposeNode(Composables.kt:<unknown line>)
    at Layout(Layout.kt:79)
    at <lambda>(TempErrorsTest.kt:164)
    at <lambda>(BoxWithConstraints.kt:66)
    at ReusableContentHost(Composables.kt:164)
    at <lambda>(SubcomposeLayout.kt:514)
    at SubcomposeLayout(SubcomposeLayout.kt:114)
    at SubcomposeLayout(SubcomposeLayout.kt:80)
    at BoxWithConstraints(BoxWithConstraints.kt:64)
    at SubcomposeLayoutErrorComposable(TempErrorsTest.kt:164)
    at <lambda>(TempErrorsTest.kt:86)
    at Content(ComposeView.android.kt:430)
    at <lambda>(ComposeView.android.kt:249)
    at CompositionLocalProvider(CompositionLocal.kt:364)
    at ProvideCommonCompositionLocals(CompositionLocals.kt:193)
    at <lambda>(AndroidCompositionLocals.android.kt:113)
    at CompositionLocalProvider(CompositionLocal.kt:364)
    at ProvideAndroidCompositionLocals(AndroidCompositionLocals.android.kt:102)
    at <lambda>(Wrapper.android.kt:141)
    at CompositionLocalProvider(CompositionLocal.kt:384)
    at <lambda>(Wrapper.android.kt:140)

Bilinen sınırlamalar

Yığın izleme çerçeveleriyle ilgili bilinen birkaç sorun vardır:

Kaynak bilgisi yığın izlemeleri

Oluşturma sırasındaki kilitlenmeler için ilk yığın çerçevesinde satır numaraları (<unknown line>) eksik. Kaynak bilgileri incelemesi kilitlenmeden sonra gerçekleştiği için yuva tablosu verileri eksik olabilir ve satır numarası düşebilir. ReusableComposeNode ve remember, kaynak bilgisi üretmediğinden bu işlevlerin yığın çerçevelerinde <unknown line> ifadesini görürsünüz.

Grup anahtarları yığın izlemeleri

GroupKeys tabanlı yığın izlemeler, tasarım gereği yalnızca @Composable işlevinin ilk satırını gösterebilir. Ayrıca, grup oluşturmayan işlevler (ör. satır içi veya birim döndürmeyen işlevler) için veri içermezler.

Yığın izleme koleksiyonu kilitlenmeleri

Yığın izleme koleksiyonu herhangi bir nedenle kilitlenirse bu istisna, DiagnosticComposeException yerine bastırılmış bir istisna olarak eklenir.

Gizlenen kilitlenmeleri veya yığın izleme tutarsızlıklarını Compose çalışma zamanı bileşenine bildirin.