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

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

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

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

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

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

  • قطعه موسیقی
  • ‫DisposableEffect و LaunchedEffect (به‌جز onDispose یا لغو)
  • ‫Coroutines در 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 تابع استفاده می‌شود. این ردیابی‌های پشته‌ای دقت کمتری دارند و برای جلوگیری از انجام کار اضافی در زمان اجرا بهینه شده‌اند. گردآورنده «نوشتن» از انتشار نگاشت‌های اضافی 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 اشاره کند. همچنین این فایل‌ها حاوی داده‌های مربوط به هیچ‌یک از توابعی که گروه تولید نمی‌کنند (مثل توابع درون‌خطی یا توابعی که نوع «واحد» را برنمی‌گردانند) نیستند

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

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

هرگونه خرابی سرکوب‌شده یا ناسازگاری ردیابی پشته را به جزء زمان اجرای Compose گزارش دهید.