هنگام کار با قوانین نگهداری، مهم است که به میزان مناسبی از جزئیات برسید تا مطمئن شوید که ضمن حفظ رفتار برنامهتان، از مزایای آن بهرهمند میشوید. برای آشنایی با الگوهای خوب و همچنین مواردی که باید در قوانین نگهداری از آنها اجتناب کنید، بخشهای زیر را ببینید.
الگوهای خوب در قوانین نگهداری
قوانین نگهداری بهخوبی تعریفشده تا حد امکان دقیق هستند و از الگوهای زیر پیروی میکنند:
برای مشخصات کلاس، همیشه کلاس خاص، کلاس پایه، یا کلاس حاشیهنویسیشده را درصورت امکان مشخص کنید، همانطور که در مثالهای زیر نشان داده شده است:
-keepclassmembers class com.example.MyClass { void someSpecificMethod(); }-keepclassmembers ** extends com.example.MyBaseClass { void someSpecificMethod(); }-keepclassmembers @com.example.MyAnnotation class ** { void someSpecificMethod(); }هر زمان که ممکن است، از حاشیهنویسی در کد منبع خود استفاده کنید و سپس آن حاشیهنویسیها را مستقیماً در قوانین نگهداری خود هدف قرار دهید. این کار پیوندی واضح و صریح بین کد شما و قوانینی که آن را حفظ میکنند ایجاد میکند و پیکربندی شما را قویتر، قابلفهمتر، و کمتر مستعد خرابی درصورت تغییر کد میکند.
برای مثال، گزیده زیر نشان میدهد چگونه میتوانید کلاس MyClass و همچنین کلاسهای دیگری را که با
@com.example.DisplayComponentحاشیهنویسی شدهاند حفظ کنید:// In the source code @com.example.DisplayComponent class MyClass { /* ... */ } // In the keep rules -keep @com.example.DisplayComponent class * {*;}توصیه میکنیم حاشیهنویسیهایتان را بهگونهای نامگذاری کنید که بافت معناداری برای دلیل حفظ بخشهای کد ارائه دهند. برای مثال، برای برنامهای که در آن عناصر نمایشگر نیاز دارد برخیاز بخشها حفظ شود، از
@DisplayComponentاستفاده کنید.هرگاه ممکن بود، مشخصات عضو باید اعلام شود و فقط به بخشهایی از کلاس ارجاع داده شود که برای عملکرد برنامه باید حفظ شود. توصیه میشود قانونی را با تعریف کردن دامنه عضو اختیاری بهعنوان
{ *; }بر کل کلاس اعمال نکنید، مگراینکه واقعاً لازم باشد.-keepclassmembers com.example.MyClass { void someSpecificMethod(); void @com.example.MyAnnotation *; }اگر از
repackageclassesگزینه جهانی استفاده میکنید، از مشخص کردن نام بسته اختیاری خودداری کنید. این کار باعث میشود فایلهای DEX کوچکتر شوند زیرا پیشوند بسته در نامهای کلاس بستهبندیشده مجدد حذف میشود.قوانین نگهداری را برای همه موارد دسترسییافته ازطریق بازتاب حفظ کنید. حتی اگر چنین مواردی بدون قوانین حفظ صریح توسط R8 حفظ شوند، حفظ قوانین واقعی حیاتی است زیرا تغییرات کد آینده میتواند منجر به این شود که R8 دیگر این موارد را حفظ نکند.
برای بازتاب در کد خودتان، میتوانید از Jetpack Keep برای تولید قوانین نگهداری که نگهداری آنها آسانتر است استفاده کنید. هر حاشیهنویسی روی کدی است که بازتاب را انجام میدهد، بنابراین وقتی آن کد را تغییر میدهید، حاشیهنویسی آن را در همان مکان بهروزرسانی یا حذف میکنید. به این ترتیب، قوانین کدی را که برنامهتان دیگر به آن ارجاع نمیدهد حفظ نمیکنند. Lint همچنین فراخوانیهای بازتابی را که حاشیهنویسی نشدهاند پرچمگذاری میکند.
درصورت امکان، از
-assumenosideeffectsیا-convertchecknotnullبرای بهینهسازی بررسیهای تهی استفاده کنید زیرا این کار میتواند اندازه DEX برنامهتان را بهطور قابلتوجهی کاهش دهد. برای اطلاعات بیشتر، انواع قانون اضافی را ببینید.
اگر نمیتوانید از این دستورالعملها پیروی کنید، میتوانید موقتاً کدی را که باید در بسته اختصاصی نگهداری شود جدا کنید و قانون نگهداری را برای آن بسته اعمال کنید. بااینحال، این راهحلی بلندمدت نیست. برای کسب اطلاعات بیشتر، به پذیرفتن بهینهسازیها بهصورت افزایشی مراجعه کنید. برای استفاده از قانون نگهداری برای یک بسته، قانون نگهداری را همانطور که در مثال زیر نشان داده شده است تعریف کنید:
-keepclassmembers class com.example.pkg.** { *; }
مواردی که باید از آنها اجتناب کنید
نحو قانون نگهداری گزینههای زیادی دارد، اما برای مزایای عملکرد پایدار قابلاندازهگیری، توصیه میکنیم از موارد زیر استفاده نکنید:
- از قوانین نگهداری در سطح بسته مثل
-keep class com.example.pkg.** { *; }بلندمدت استفاده نکنید. میتوان از آنها بهطور موقت برای حل مشکلات هنگام پیکربندی R8 استفاده کرد. برای اطلاعات بیشتر، محدود کردن دامنه بهینهسازی را ببینید. بهطورکلی، دراستفاده از نویسههای عام دقت کنید— مطمئن شوید که فقط کدهایی را نگه میدارید که به آنها نیاز دارید. - درصورت امکان، از کتابخانههایی که پیشنهاد میکنند هنگام استفاده از آنها، بهویژه قوانین نگهداری در سطح بسته، قوانین نگهداری را کپی و جایگذاری کنید، اجتناب کنید. کتابخانههایی که برای عملکرد خوب در Android طراحی شدهاند باید تا حد امکان از بازتاب اجتناب کنند و درصورت لزوم، قوانین حفظ مصرفکننده را جاسازی کنند.
- از بهکار بردن عملگر وارونگی
!در قوانین نگهداری خودداری کنید زیرا ممکن است بهطور ناخواسته قانونی را برای تقریباً همه کلاسهای برنامهتان اعمال کنید.
اگر نمیتوانید این قوانین را دنبال کنید، احتمالاً از بازتابهای بیپایان زیادی استفاده میکنید و باید از بازتاب یا استفاده از کتابخانه بااستفاده از بازتاب اجتناب کنید (مطالعه موردی Gson را ببینید).