ردیابی پشته‌ای در Compose

Jetpack Compose کد شما را در چند فاز مختلف اجرا می‌کند که باعث می‌شود برخی‌از بخش‌های تابع @Composable جدا از یکدیگر اجرا شوند. ازکارافتادن در این مراحل می‌تواند منجر به ردیابی پشته‌ای شود که رمزگشایی آن دشوار است، و این امر تعیین دقیق تابع یا خط کد ایجادکننده ازکارافتادن را دشوار می‌کند.

افزودن اطلاعات منبع به ردیابی پشته

برای بهبود خوانایی ردیابی پشته‌ای، یک میانای برنامه‌سازی کاربردی اختیاری جزئیات غنی‌تری از مکان خرابی ارائه می‌دهد، ازجمله نام‌ها و مکان‌های قابل‌ترکیب، که به شما امکان می‌دهد:

  • شناسایی و حل مؤثر منابع خرابی
  • جداسازی خرابی‌ها برای نمونه‌های قابل‌تولید مجدد
  • خرابی‌هایی را که قبلاً فقط چارچوب‌های پشته‌ای داخلی را نشان می‌دادند بررسی کنید

زمان اجرای Compose می‌تواند مکان ازکارافتادن را در ترکیب‌بندی شناسایی کند و رد پشته‌ای را براساس سلسله‌مراتب @Composable شما بازسازی کند. ردیابی پشته‌ای برای خرابی‌ها در این موارد اضافه شده است:

  • قطعه موسیقی
  • DisposableEffect و LaunchedEffect (به‌جز onDispose یا لغو)
  • روال‌های همگام راه‌اندازی‌شده در rememberCoroutineScope
  • اندازه‌گیری، چیدمان، و ترسیم مجوزها

برای فعال کردن این ویژگی، خطوط زیر را به نقطه ورودی برنامه اضافه کنید:

// 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)
    }
}

در حالت ایده‌آل، این پیکربندی را قبل‌از ایجاد هرگونه ترکیب‌بندی انجام دهید تا مطمئن شوید که اطلاعات ردیابی پشته به‌درستی جمع‌آوری می‌شود.

چهار گزینه برای ComposeStackTraceMode وجود دارد:

  • Auto: گزینه توصیه‌شده، زیرا اگر برنامه کوچک‌سازی شده باشد از GroupKeys استفاده می‌کند و درغیراین‌صورت از None.
  • GroupKeys: ردیابی‌های پشته‌ای برای برنامه‌های کوچک‌شده ایجاد شده است. اطلاعات کلید گروه حتی پس‌از خلاصه‌سازی کد منبع حفظ می‌شود و همراه با فایل نگاشت proguard که توسط کامپایلر Compose و R8 منتشر شده است برای بازسازی مکان تقریبی توابع @Composable استفاده می‌شود. این ردیابی‌های پشته‌ای دقت کمتری دارند و برای جلوگیری از انجام کار اضافی در زمان اجرا بهینه‌سازی شده‌اند. کامپایلر Compose از انتشار نگاشت‌های R8 اضافی از Kotlin نسخه 2.3.0 پشتیبانی می‌کند.
  • SourceInformation: برای ساخت‌های غیرکوچک‌شده مفید است، اطلاعات منبع را جمع‌آوری می‌کند و آن را به ردیابی پشته‌ای اضافه می‌کند. نتایج دقیق‌تر هستند، اما هزینه عملکرد قابل‌توجهی را متحمل می‌شوند که مشابه پیوست کردن «بازرس چیدمان» است. این نمادها برای استفاده در نسخه‌های اشکال‌زدایی برنامه‌ها ایجاد می‌شوند تا اطلاعات دقیقی درباره خرابی‌هایی که به اطلاعات بیشتری درباره مکانشان نیاز دارند به‌دست آید. اطلاعات منبع از برنامه‌های کوچک‌شده برداشته می‌شود تا اندازه و عملکرد دودویی بهینه‌سازی شود.
  • None: جزئیات ردیابی پشته‌ای اضافی اضافه نشده است.

هنگام استفاده از گزینه SourceInformation، ردیابی پشته به‌صورت DiagnosticComposeException در فهرست استثناهای سرکوب‌شده نشان داده می‌شود:

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)

محدودیت‌های شناخته‌شده

چند مشکل شناخته‌شده با قاب‌های ردیابی پشته وجود دارد:

ردیابی‌های پشته‌ای اطلاعات منبع

شماره خطوط (<unknown line>) در اولین چارچوب پشته‌ای برای خرابی‌ها در ترکیب‌بندی وجود ندارد. ازآنجایی‌که درون‌نگری اطلاعات منبع پس‌از خرابی اتفاق می‌افتد، داده‌های جدول جایگاه می‌تواند ناقص باشد و شماره خط را حذف کند. ReusableComposeNode و remember اطلاعات منبع تولید نمی‌کنند، بنابراین <unknown line> را در چارچوب‌های پشته‌ای برای آن توابع خواهید دید.

ردیابی‌های پشته‌ای کلیدهای گروهی

ردگیری‌های پشته مبتنی بر GroupKeys فقط می‌توانند به خط اول @Composable تابع طراحی اشاره کنند. همچنین حاوی هیچ داده‌ای برای هیچ‌یک از توابعی که گروه تولید نمی‌کنند (مثل توابع درون‌خطی یا توابعی که Unit برنمی‌گردانند) نیستند

ازکارافتادن جمع‌آوری ردیابی پشته‌ای

اگر مجموعه ردیابی پشته‌ای به هر دلیلی ازکار بیفتد، آن استثنا به‌جای DiagnosticComposeException به‌عنوان استثنای سرکوب‌شده اضافه می‌شود.

هرگونه خرابی سرکوب‌شده یا ناهماهنگی ردیابی پشته را به مؤلفه Compose Runtime گزارش کنید.