برای فعال کردن بهینه سازی اپلیکیشن ها، باید از کتابخانه هایی استفاده کنید که با بهینه سازی اندروید سازگار هستند. اگر کتابخانهای برای بهینهسازی اندروید پیکربندی نشده باشد - به عنوان مثال، اگر از بازتاب بدون بستهبندی قوانین حفظ مرتبط استفاده میکند - ممکن است برای یک برنامه Android مناسب نباشد. این صفحه توضیح میدهد که چرا برخی از کتابخانهها برای بهینهسازی برنامهها مناسبتر هستند و نکات کلی را برای کمک به شما در انتخاب ارائه میدهد.
کدژن را به بازتاب ترجیح دهید
به طور کلی، شما باید کتابخانه هایی را انتخاب کنید که به جای بازتاب از تولید کد ( کدژن ) استفاده می کنند. با کدژن، بهینهساز میتواند راحتتر تعیین کند که واقعاً چه کدی در زمان اجرا استفاده میشود و کدام کد را میتوان حذف کرد. تشخیص اینکه آیا یک کتابخانه از کدژن یا بازتاب استفاده میکند ممکن است دشوار باشد، اما برخی از نشانهها وجود دارد—برای کمک به راهنماییها مراجعه کنید.
برای اطلاعات بیشتر در مورد کدژن در مقابل بازتاب، به بهینه سازی برای نویسندگان کتابخانه مراجعه کنید.
نکات کلی در انتخاب کتابخانه ها
از این نکات برای اطمینان از سازگاری کتابخانه های شما با بهینه سازی برنامه استفاده کنید.
مشکلات بهینه سازی را بررسی کنید
هنگام در نظر گرفتن یک کتابخانه جدید، از طریق ردیاب مشکل کتابخانه و بحث های آنلاین نگاه کنید تا بررسی کنید که آیا مسائل مربوط به کوچک سازی یا پیکربندی بهینه سازی برنامه وجود دارد یا خیر. اگر وجود دارد، باید سعی کنید به دنبال جایگزین هایی برای آن کتابخانه باشید. موارد زیر را در نظر داشته باشید:
- کتابخانههای AndroidX و کتابخانههایی مانند Hilt با بهینهسازی برنامهها به خوبی کار میکنند زیرا به جای بازتاب از کدژن استفاده میکنند. هنگامی که آنها از بازتاب استفاده می کنند، حداقل قوانین حفظ را ارائه می کنند تا فقط کد مورد نیاز را حفظ کنند.
- کتابخانههای سریالسازی اغلب از بازتاب استفاده میکنند تا هنگام نمونهسازی یا سریالسازی اشیاء، از کد boilerplate اجتناب کنند. به جای رویکردهای مبتنی بر بازتاب (مانند Gson برای JSON)، به دنبال کتابخانههایی باشید که از کدژن برای جلوگیری از این مشکلات استفاده میکنند، برای مثال با استفاده از Kotlin Serialization .
- در صورت امکان باید از کتابخانه هایی که شامل قوانین نگهداری در سطح بسته هستند اجتناب شود. قوانین نگهداری در کل بسته می تواند به رفع خطاها کمک کند، اما قوانین نگهداری گسترده در نهایت باید اصلاح شوند تا فقط کد مورد نیاز حفظ شود. برای اطلاعات بیشتر، به پذیرش بهینه سازی به صورت تدریجی مراجعه کنید.
پس از افزودن یک کتابخانه جدید، بهینه سازی را فعال کنید
هنگامی که یک کتابخانه جدید اضافه می کنید، پس از آن بهینه سازی را فعال کنید و بررسی کنید که آیا خطا وجود دارد. اگر خطایی وجود دارد، به دنبال جایگزین هایی برای آن کتابخانه باشید یا قوانین حفظ را بنویسید. اگر کتابخانه ای با بهینه سازی سازگار نیست، باگ را در آن کتابخانه ثبت کنید.
قوانین افزودنی هستند
توجه داشته باشید که قوانین حفظ، افزودنی هستند. این بدان معنی است که قوانین خاصی که وابستگی کتابخانه شامل آن می شود را نمی توان حذف کرد و ممکن است بر گردآوری سایر بخش های برنامه شما تأثیر بگذارد. به عنوان مثال، اگر یک کتابخانه شامل یک قانون برای غیرفعال کردن بهینه سازی کد باشد، آن قانون بهینه سازی را برای کل پروژه شما غیرفعال می کند.
بررسی استفاده از بازتاب (پیشرفته)
ممکن است بتوانید تشخیص دهید که آیا کتابخانه ای از بازرسی کد خود از بازتاب استفاده می کند. اگر کتابخانه از بازتاب استفاده می کند، بررسی کنید که قوانین نگهداری مرتبط را ارائه می دهد. یک کتابخانه احتمالاً از بازتاب استفاده می کند اگر موارد زیر را انجام دهد:
- از کلاس ها یا متدهای بسته های
kotlin.reflect
یاjava.lang.reflect
استفاده می کند. - از توابع
Class.forName
یاclassLoader.getClass
استفاده می کند - حاشیه نویسی ها را در زمان اجرا می خواند، برای مثال اگر یک مقدار حاشیه نویسی را با استفاده از
val value = myClass.getAnnotation()
یاval value = myMethod.getAnnotation()
ذخیره می کند و سپس کاری باvalue
انجام می دهد. متدها را با استفاده از نام متد به عنوان رشته فراخوانی می کند، به عنوان مثال:
// Calls the private `processData` API with reflection myObject.javaClass.getMethod("processData", DataType::class.java) ?.invoke(myObject, data)
فیلتر کردن قوانین نگهداری بد (پیشرفته)
باید از کتابخانه هایی با قوانین حفظ که کدهایی را که واقعاً باید حذف شوند، حفظ کنید، اجتناب کنید. اما اگر باید از آنها استفاده کنید، می توانید قوانین را همانطور که در کد زیر نشان داده شده است فیلتر کنید:
// If you're using AGP 8.4 and higher
buildTypes {
release {
optimization.keepRules {
it.ignoreFrom("com.somelibrary:somelibrary")
}
}
}
// If you're using AGP 7.3-8.3
buildTypes {
release {
optimization.keepRules {
it.ignoreExternalDependencies("com.somelibrary:somelibrary")
}
}
}
مطالعه موردی: چرا Gson با بهینه سازی ها شکست می خورد
Gson یک کتابخانه سریالسازی است که اغلب مشکلاتی را در بهینهسازی برنامه ایجاد میکند، زیرا به شدت از بازتاب استفاده میکند. قطعه کد زیر نحوه استفاده از Gson را نشان می دهد که به راحتی می تواند باعث خرابی در زمان اجرا شود. توجه داشته باشید که وقتی از Gson برای دریافت لیستی از اشیاء کاربر استفاده می کنید، سازنده را فراخوانی نمی کنید یا کارخانه ای را به تابع fromJson()
منتقل نمی کنید. ساختن یا مصرف کلاس های تعریف شده توسط برنامه بدون هیچ یک از موارد زیر نشانه این است که یک کتابخانه ممکن است از بازتاب بازتاب استفاده کند:
- کلاس برنامه در حال پیاده سازی یک کتابخانه، یا رابط استاندارد یا کلاس
- پلاگین تولید کد مانند KSP
class User(val name: String)
class UserList(val users: List<User>)
// This code runs in debug mode, but crashes when optimizations are enabled
Gson().fromJson("""[{"name":"myname"}]""", User::class.java).toString()
وقتی R8 این کد را تجزیه و تحلیل میکند و UserList
یا User
را در جایی نمیبیند، میتواند نام فیلدها را تغییر دهد یا سازندههایی را که به نظر میرسد استفاده نمیشوند حذف کند و باعث از کار افتادن برنامه شما شود. اگر از کتابخانههای دیگری به روشهای مشابه استفاده میکنید، باید بررسی کنید که با بهینهسازی برنامهها تداخل نداشته باشند، و اگر چنین کردند، از آنها اجتناب کنید.
توجه داشته باشید که Room و Hilt هر دو انواع تعریف شده برنامه را می سازند، اما برای اجتناب از نیاز به بازتاب از کدژن استفاده می کنند.