استفاده از قوانین برای عیب‌یابی بهینه‌سازی

جدا از قوانین کلی keep ، انواع قوانین keep اضافی و گزینه‌های سراسری ، می‌توانید از قوانین خاصی برای عیب‌یابی بهینه‌سازی خود استفاده کنید.

-checkdiscard

دستور -checkdiscard ‎ به شما امکان می‌دهد بررسی کنید که آیا R8 با موفقیت یک کلاس یا عضو آن را که انتظار داشتید حذف شود، حذف کرده است یا خیر. اگر کلاس یا عضو مشخص شده حذف نشود، ساخت با شکست مواجه می‌شود.

سینتکس -checkdiscard ‎ به شرح زیر است:


-checkdiscard <class_specification>

در مثال زیر، اگر فیلد userId یا متد setLabel() از کلاس com.example.models.User حفظ شوند، ساخت با شکست مواجه می‌شود:

-checkdiscard class com.example.models.User{
  private java.lang.String userId;
  public void setLabel(java.lang.String);
}

اگر متدهای کلاس در کلاس‌های دیگر به صورت درون‌خطی (inline) تعریف شده باشند، ممکن است کد آن کلاس هنوز در برنامه وجود داشته باشد. برای اطمینان از اینکه کد به طور کامل حذف شده و فقط درون‌خطی نشده است، یک قانون مربوطه اضافه کنید که مانع از انجام بهینه‌سازی‌ها روی کلاس هدف توسط R8 شود. این کار با ترکیب -checkdiscard ‎ با قانون -keep,allowshrinking ‎ انجام می‌شود. این کار بهینه‌سازی‌هایی مانند ادغام کلاس و درون‌خطی کردن را ممنوع می‌کند. اگر قانون -checkdiscard ‎ با موفقیت اجرا شود، هیچ یک از محتویات کلاس‌های منطبق در برنامه بهینه‌سازی شده وجود نخواهد داشت.

مثال زیر این کاربرد را نشان می‌دهد:

# Either keep or remove the class, don't rename or otherwise optimize it
-keep,allowshrinking class com.example.foo { *; }

# Verify that the class and all of its fields and methods are removed.
-checkdiscard class com.example.foo

-whyareyoukeeping

از قانون -whyareyoukeeping برای تعیین اینکه چرا R8 یک کلاس، فیلد یا متد خاص را در ساخت برنامه شما نگه داشته است، استفاده کنید. یک آیتم می‌تواند به دلایل مختلف نگه داشته شود؛ با این حال، این قانون فقط قانونی را ارائه می‌دهد که کوتاه‌ترین مسیر به آیتم را از یک آیتم نگه داشته شده توضیح می‌دهد. اگر این مسیر را از کد خود حذف کنید، ممکن است همچنان آیتم را حفظ شده ببینید، اما به دلیل دیگری.

دلایل احتمالی عبارتند از:

  • یک قانون نگهداری : قانون نگهداری می‌تواند از برنامه، یک کتابخانه مصرف‌شده یا قوانینی باشد که توسط AAPT (ابزار بسته‌بندی دارایی‌های اندروید) تولید شده است.

  • ارجاعات انتقالی از کد یا منابع نگهداری‌شده : اگر کد یا XML (مانند طرح‌بندی‌ها) توسط R8 حفظ شود، هر چیزی که به صورت ایستا به آن ارجاع داده می‌شود، حفظ خواهد شد.

نحو آن این است:


-whyareyoukeeping <class_specification>

برای مثال:

-whyareyoukeeping class com.example.foo.MainActivity {
  private void setLabel(...);
}

خروجی در کنسول چاپ می‌شود.

اگر هیچ قانونی برای نگهداری setLabel() نداشته باشید، خروجی به صورت زیر خواهد بود:

com.example.foo.MainActivity
|- is referenced in keep rule:
|  /app/build/intermediates/aapt_proguard_file/release/processReleaseResources/aapt_rules.txt:4:1
Nothing is keeping void com.example.foo.MainActivity.setLabel()

اگر قانون keep را روی setLabel() تنظیم کرده باشید، خروجی مشابه زیر خواهد بود:

com.example.foo.MainActivity
|- is referenced in keep rule:
| /app/proguard-rules.pro:23:1
void com.example.foo.MainActivity.setLabel()
|- is referenced in keep rule:
|  /app/proguard-rules.pro:23:1