سلام دوستان عزیز عرض ارادت ، دوست دارم توی این مقاله در مورد proguard ها و R8 در اندوید آشنا بشیم و لازم بذکره که این مقاله جهت افرادی ایجاد شده که در برنامه نویسی اندروید سطح مبتدی را رد کردند و به سطح متوسط و نیمه حرفه ای یا حرفه ای رسیدند .
اگه شما حداقل یک برنامه اندروید نوشته باشین حتما به این نکته توجه داشتین که حجم نسخه پایانی یا همون نسخه Release بسیار مهمه و هرچه حجم فایل خروجی البته بسته به میزان کد نویسی شما پایین تر باشه کارفرما و کاربران راضی تر خواهند بود . که یکی از وظایف proguard و R8 در اندروید کاهش و بهینه سازی حجم نسخه خروجی اپلیکیشن شما می باشد
پروگارد و R8 دارای Task هایی می باشند که در زمان کامپایل برای شما فراهم میکنند و باعث بهینه سازی و افزایش امینیت کد ها بواسطه تغییر نام کلاس ها ، توابع و متغیر ها ، درک و خواندن کد ها را برای decompiler ها سخت یا حتی غیر ممکن مینماید.
به زبان ساده تر کامپایل کردن جهت دریافت نسخه خروجی : یکسری فرایند هایی هستند که با اجرا شدن بترتیب آنها از کدهای ایجاد شده ما نسخه خروجی و فایل نصبی تهیه مینمایند . حال با decompile کردن یا مهندسی معکوس کردن این فرانید (وب سایت های بسیاری هستند که این کار را با یک کلیک انجام میدهند) میتوانند از نسخه خروجی کدهای اپلیکیشن شما را استخراج نمایند . البته این کد ها خوانایی زیادی ندارند ولی اگر در دست decompiler هایی حرفه ای قرار گیرد میتوانند اطلاعات مفیدی از کد هایی شما بدست آورند.
به هنگام ایجاد اپلیکیشن مقدار زیادی از کد و کتابخانه های بلا استفاده و در کد های ما ایجاد می شود که باعث افزایش سایز بسته خروجی اپلیکیشن ما میشود . با فعال نمودن Proguard یا r8 این کد های بلا استفاده حذف شده و کد هایی باقی مانده را بهینه سازی کرده و با تغییر نام کلاس ها ، توابع یا متغیر ها کد ها را بهینه و خوانایی آنها را در هنگام decompile بسیار پایین و حتی غیر ممکن مینماید و امنیت کد ها را به سطح مناسبی میرساند .
1-Shrink or tree shaking : کوچک کردن یا لرزش درختی
حذف کلاس ها ، فیلد ها و متغیر های بلا استفاده
2- code optimization : بهینه سازی کد ها
کد ها را در سطح ساختاری کوچک تر و کارامد تر می کند
3- identifier renaming : تغییر نام به نام های بی معنا
در این مرحله نام کلاس ها ، توابع و متغیر ها با نام های کوتاه و بی معنا تغییر می دهد و از سایز اپلیکیشن کاهش می دهد
برای اثبات این موضوع استناد می کنیم به تحقیقاتی که بروی R8 در سال 2019 توسط تیم توسعه دهندگان اندروید summit جهت کاهش سایز بروی یک اپلیکشن ساده اندروید انجام پذیرفت .
آنها یک اپلیکیشن ساده که فقط حاوی یک Activity و با زبان kotlin قبل از استفاده از R8 سایز نسخه خروجی 3.444 kb بود و پس از فعال سازی R8 سایز آن به 780 kb کاهش یافت که نتیجه حاصله 2.644 kb بوده که چیزی حدود 70% کمتر از نسخه خروجی قبل از فعال سازی R8 می باشد.
سپس همان اپلیکیشن را به همراه کتابخانه okhttp برسی کردند و قبل از فعال بودن R8 سایز آن 4.134kb و پس از فعال کردن R8 خروجی 780kb شد که نتیجه حاصل شده 79% کاهش حجم فایل خروجی بود
برای فعال نمودن ، کافیست قطعه کد زیر را در فایل build.gradle فعال کنیم
buildTypes { release { minifyEnabled false --> true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } }
1-minifyEnabled برای فعال یا غیر فعال نمودن Proguard مورد استفاده قرار میگیرد
2-proguard-android-optimize.txt فایلی است حاوی قوانین از پیش تعریف شده برای Proguard میباشد
3-proguard-rules.pro فایل خالی است که بطور پیش فرض ایجاد شده و جهت ایجاد قوانین دستی استفاده می شود
هنگامی که ما Proguard یا R8 را فعال مینماییم بطور پیش فرض تمامی سه توابع بروی تمامی کلاس ها و توابع ما فعال می شود ولی گاهی اوقات نیاز است که کلاسی خاص یا توابع یا متغیر هایی خاص مورد استثناء قرار گیرد.
برای مثال اگر شما با کتابخانه Gson آشنا باشید ، این کتابخانه وظیفه تبدیل کد های json را به Object ها در اندروید بر عهده دارد .در این کتابخانه نام متغیر های model ارسالی بسیار مهم می باشد و اگر تغییر کند مقدار بازگشتی متغیر ها null خواهد بود . برای جلوگیری از این کار توسط Proguard یا R8 ما مجموعه قوانینی وضع می نماییم که بعضی از کلاس ها , توابع و یا متغیر ها را استثنا قرار دهد .
شاید در ابتدا برای شما کمی استفاده از این نوع کد ها بسیار سخت باشد ولی پس از استفاده پی خواهید برد که نوشتن قوانین ساده تر از حد تصور شما خواهد بود
keep
با استفاده از این دستور شما میتوانید یک کلاس را مورد استثناء قرار دهید
-keep class com.example.Data.Model.user { <fields>; }
با استفاد از قوانین بالا ما میتونیم تمام فیلد های کلاس user را استثناء قرار دهیم
1-Api model - room model
این نوع کلاس ها جهت جلوگیری از تغیر نام در Proguard مورد استثناء قرار دهید.
بدلیل اینکه کتابخانه Gson وابسته به نام متغیر ها می باشد و با تغیر نام متغیر ها ، نتیجه حاصله Null خواهد بود
2-Fragment Tag
وقتی ما از Fragment ها استفاده می نماییم متغیر رشته ای با نام Tag استفاده میکنیم که بطور معمول بصورت زیر معرفی می کنیم .
String Tag=MusicPlayerFragment.class.getSimpleName();
بطور خیلی خلاصه بگم چون توضیح این قسمت خودش یه مقاله میشه
اگر ما دو Fragment داشته باشیم و نام های اونها متفاوت بشه ولی Proguard نام های اون ها را تغیر میده ولی اگر نام Fragment ها را به a (برای مثال ) تغییر بده حال Tag ها شبیه به هم میشند و در نهایت در هنگام اجرای برنامه به ایراد بر می خوریم
پس بهتره Tag ها را به شکل زیر تعریف کنیم
String Tag="MusicPlayerFragment"
3-Component Class
بدلیل اینکه در فایل های Xml ما از کامپوننت ها استفاده میکنیم و اگر نام آنها تغییر کند برنامه در هنگام اجرا به ایراد بر میخورد
4-add library rules to Proguard
پس از افزودن کتابخانه های توجه کنید که اگر از قوانین خاصی استفاده می کند آن را در فایل proguard-rules.pro اپلیکیشن خود قرار دهید
5-dont change native class name
توجه شود که اگر از کتابخانه های native که با زبان های c++ در اپلیکیشن استفاده می شود در قسمت قوانین پروگارد قرار گیرد
دوستان عزیز برای تهیه این مقاله بیش از 20 مقاله زبان اصلی مطالعه شد و سعی شد بدیلی اینکه چنین مقاله ای به زبان فارسی در دسترس نبود بصورت خیلی ساده شرح داده شود
ممنون بابت اینکه وقت گرانبهاتون را به خوندن این مقاله اختصاص دادین و اگه دوست داشتین لایک کنین و نظر بدین تا از نظرات ارزشمندتون در مقاله های بعدی استفاده کنیم