به عنوان یک نویسنده کتابخانه، باید مطمئن شوید که توسعه دهندگان برنامه می توانند به راحتی کتابخانه شما را در برنامه خود بگنجانند و در عین حال تجربه کاربر نهایی با کیفیت بالا را حفظ کنند. باید مطمئن شوید که کتابخانه شما بدون راهاندازی اضافی با بهینهسازی Android سازگار است - یا سندی مبنی بر اینکه کتابخانه ممکن است برای استفاده در Android نامناسب باشد.
این مستندات برای توسعه دهندگان کتابخانه های منتشر شده هدف قرار می گیرد، اما ممکن است برای توسعه دهندگان ماژول های کتابخانه داخلی در یک برنامه بزرگ و مدولار شده نیز مفید باشد.
اگر توسعهدهنده برنامه هستید و میخواهید درباره بهینهسازی برنامه Android خود بیاموزید، به فعال کردن بهینهسازی برنامه مراجعه کنید. برای اطلاع از اینکه کدام کتابخانه ها برای استفاده مناسب هستند، به انتخاب عاقلانه کتابخانه ها مراجعه کنید.
از کدژن بر روی بازتاب استفاده کنید
در صورت امکان، از تولید کد ( کدژن ) بر روی بازتاب استفاده کنید. کدژن و انعکاس هر دو رویکردهای رایج برای جلوگیری از کد دیگ بخار در هنگام برنامه نویسی هستند، اما کدژن با بهینه ساز برنامه مانند R8 سازگارتر است:
- با کدژن، کد در طول فرآیند ساخت، تجزیه و تحلیل و اصلاح می شود. از آنجایی که پس از زمان کامپایل هیچ تغییر عمدهای وجود ندارد، بهینهساز میداند که در نهایت به چه کدی نیاز است و چه چیزی را میتوان با خیال راحت حذف کرد.
- با بازتاب، کد در زمان اجرا تجزیه و تحلیل و دستکاری می شود. از آنجایی که کد تا زمانی که اجرا نشود واقعاً نهایی نمی شود، بهینه ساز نمی داند چه کدی را می توان با خیال راحت حذف کرد. احتمالاً کدهایی را که به صورت پویا از طریق بازتاب در زمان اجرا استفاده میشوند، حذف میکند، که باعث خرابی برنامه برای کاربران میشود.
بسیاری از کتابخانه های مدرن به جای بازتاب از کدژن استفاده می کنند. KSP را برای یک ورودی مشترک که توسط Room ، Dagger2 و بسیاری دیگر استفاده میشود، ببینید.
وقتی بازتاب مشکلی ندارد
اگر باید از بازتاب استفاده کنید، فقط باید به یکی از موارد زیر فکر کنید:
- انواع هدفمند خاص (پیادهکنندههای رابط یا زیر کلاسهای خاص)
- کد با استفاده از یک حاشیه نویسی زمان اجرا خاص
استفاده از بازتاب در این روش هزینه زمان اجرا را محدود می کند و نوشتن قوانین حفظ مشتری هدفمند را امکان پذیر می کند.
این شکل خاص و هدفمند انعکاس، الگویی است که میتوانید هم در چارچوب Android (مثلاً هنگام افزایش فعالیتها، نماها و نقشهها) و هم در کتابخانههای AndroidX (به عنوان مثال هنگام ساخت WorkManager ListenableWorkers یا RoomDatabases) مشاهده کنید. در مقابل، بازتاب باز Gson برای استفاده در برنامههای Android مناسب نیست .
قوانین حفظ مصرف کننده را بنویسید
کتابخانهها باید قوانین نگهداری «مصرفکننده» را بستهبندی کنند، که از همان قالب قوانین نگهداری برنامه استفاده میکنند. این قوانین در مصنوعات کتابخانه (AAR یا JAR) قرار میگیرند و در هنگام بهینهسازی برنامه Android در هنگام استفاده از کتابخانه، بهطور خودکار مصرف میشوند.
کتابخانه های AAR
برای افزودن قوانین مصرف کننده برای یک کتابخانه AAR، از گزینه consumerProguardFiles
در اسکریپت ساخت ماژول کتابخانه Android استفاده کنید. برای اطلاعات بیشتر، به راهنمای ما در مورد ایجاد ماژول های کتابخانه مراجعه کنید.
کاتلین
android { defaultConfig { consumerProguardFiles("consumer-proguard-rules.pro") } ... }
شیار
android { defaultConfig { consumerProguardFiles 'consumer-proguard-rules.pro' } ... }
کتابخانه های JAR
برای بستهبندی قوانین با کتابخانه Kotlin/Java خود که به صورت JAR ارسال میشود، فایل قوانین خود را با هر نام فایلی در فهرست نهایی META-INF/proguard/
JAR قرار دهید. به عنوان مثال، اگر کد شما در <libraryroot>/src/main/kotlin
، یک فایل قوانین مصرف کننده را در <libraryroot>/src/main/resources/META-INF/proguard/consumer-proguard-rules.pro
قرار دهید و قوانین در مکان صحیح در JAR خروجی شما قرار می گیرند.
با بررسی اینکه قوانین در دایرکتوری META-INF/proguard
قرار دارند، بررسی کنید که قوانین بستهبندی نهایی JAR به درستی انجام میشود.
بهینه سازی ساخت کتابخانه AAR (پیشرفته)
به طور کلی، شما نباید ساخت کتابخانه را مستقیماً بهینه کنید زیرا بهینه سازی های ممکن در زمان ساخت کتابخانه بسیار محدود است. تنها در طول ساخت برنامه، زمانی که یک کتابخانه به عنوان بخشی از یک برنامه کاربردی گنجانده می شود، R8 می تواند بداند که چگونه از تمام روش های کتابخانه استفاده می شود، و کدام پارامترها ارسال می شوند. بهعنوان یک توسعهدهنده کتابخانه، قبل از بهینهسازی کتابخانه، باید در مورد مراحل متعدد بهینهسازی و حفظ رفتار، هم در زمان ساخت کتابخانه و هم در زمان ساخت برنامه، استدلال کنید.
اگر همچنان میخواهید کتابخانه خود را در زمان ساخت بهینه کنید، این افزونه توسط Android Gradle پشتیبانی میشود.
کاتلین
android { buildTypes { release { isMinifyEnabled = true proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" ) } configureEach { consumerProguardFiles("consumer-rules.pro") } } }
شیار
android { buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } configureEach { consumerProguardFiles "consumer-rules.pro" } } }
توجه داشته باشید که رفتار proguardFiles
بسیار متفاوت از consumerProguardFiles
است:
-
proguardFiles
در زمان ساخت، اغلب همراه باgetDefaultProguardFile("proguard-android-optimize.txt")
استفاده می شود، تا مشخص کند کدام قسمت از کتابخانه شما باید در طول ساخت کتابخانه نگهداری شود. حداقل، این API عمومی شماست. -
consumerProguardFiles
در مقابل در کتابخانه بسته بندی می شود تا بر روی بهینه سازی هایی که بعداً در طول ساخت برنامه ای که کتابخانه شما را مصرف می کند تأثیر بگذارد.
برای مثال، اگر کتابخانه شما از بازتاب برای ساخت کلاسهای داخلی استفاده میکند، ممکن است لازم باشد قوانین keep را هم در proguardFiles
و هم consumerProguardFiles
تعریف کنید.
اگر از -repackageclasses
در ساخت کتابخانه خود استفاده می کنید، کلاس ها را به یک بسته فرعی در داخل بسته کتابخانه خود بسته بندی کنید. برای مثال، از -repackageclasses 'com.example.mylibrary.internal'
به جای -repackageclasses 'internal'
استفاده کنید.
پشتیبانی از نسخه های مختلف R8 (پیشرفته)
شما می توانید قوانینی را برای هدف قرار دادن نسخه های خاص R8 تنظیم کنید. این کار کتابخانه شما را قادر میسازد تا در پروژههایی که از نسخههای جدیدتر R8 استفاده میکنند، بهینه کار کند، در حالی که اجازه میدهد از قوانین موجود در پروژههایی با نسخههای قدیمیتر R8 استفاده شود.
برای تعیین قوانین هدفمند R8، باید آنها را در فهرست META-INF/com.android.tools
داخل classes.jar
یک AAR یا در فهرست META-INF/com.android.tools
یک JAR قرار دهید.
In an AAR library:
proguard.txt (legacy location, the file name must be "proguard.txt")
classes.jar
└── META-INF
└── com.android.tools (location of targeted R8 rules)
├── r8-from-<X>-upto-<Y>/<R8-rule-files>
└── ... (more directories with the same name format)
In a JAR library:
META-INF
├── proguard/<ProGuard-rule-files> (legacy location)
└── com.android.tools (location of targeted R8 rules)
├── r8-from-<X>-upto-<Y>/<R8-rule-files>
└── ... (more directories with the same name format)
در فهرست راهنمای META-INF/com.android.tools
، میتوان چندین زیرشاخه با نامهایی به شکل r8-from-<X>-upto-<Y>
وجود داشته باشد تا نشان دهد قوانین برای کدام نسخههای R8 نوشته شدهاند. هر زیر شاخه می تواند یک یا چند فایل حاوی قوانین R8 با هر نام و پسوند فایل داشته باشد.
توجه داشته باشید که قسمت های -from-<X>
و -upto-<Y>
اختیاری هستند، نسخه <Y>
انحصاری است و محدوده های نسخه معمولاً پیوسته هستند اما می توانند همپوشانی داشته باشند.
به عنوان مثال، r8
، r8-upto-8.0.0
، r8-from-8.0.0-upto-8.2.0
، و r8-from-8.2.0
نام دایرکتوری هایی هستند که مجموعه ای از قوانین هدفمند R8 را نشان می دهند. قوانین زیر دایرکتوری r8
توسط هر نسخه R8 قابل استفاده است. قوانین تحت پوشه r8-from-8.0.0-upto-8.2.0
می تواند توسط R8 از نسخه 8.0.0 به بالا استفاده شود، اما شامل نسخه 8.2.0 نمی شود .
افزونه Android Gradle از این اطلاعات برای انتخاب تمام قوانینی که می تواند توسط نسخه فعلی R8 استفاده شود، استفاده می کند. اگر کتابخانه ای قوانین هدفمند R8 را مشخص نکند، افزونه Android Gradle قوانین را از مکان های قدیمی انتخاب می کند ( proguard.txt
برای یک AAR یا META-INF/proguard/<ProGuard-rule-files>
برای یک JAR).