آشنایی با proguard و r8 در اندروید

سلام دوستان عزیز عرض ارادت ، دوست دارم توی این مقاله در مورد proguard ها و R8 در اندوید آشنا بشیم و لازم بذکره که این مقاله جهت افرادی ایجاد شده که در برنامه نویسی اندروید سطح مبتدی را رد کردند و به سطح متوسط و نیمه حرفه ای یا حرفه ای رسیدند . اگه شما حداقل یک برنامه اندروید نوشته باشین حتما به این نکته توجه داشتین که حجم نسخه پایانی یا همون نسخه Release بسیار مهمه و هرچه حجم فایل خروجی البته بسته به میزان کد نویسی شما پایین تر باشه کارفرما و کاربران راضی تر خواهند بود . که یکی از وظایف proguard و R8 در اندروید کاهش و بهینه سازی حجم نسخه خروجی اپلیکیشن شما می باشد proguard و R8 در اندروید چیست و چه وظایفی دارند ؟پروگارد و R8 دارای Task هایی می باشند که در زمان کامپایل برای شما فراهم میکنند و باعث بهینه سازی و افزایش امینیت کد ها بواسطه تغییر نام کلاس ها ، توابع و متغیر ها ، درک و خواندن کد ها را برای decompiler ها سخت یا حتی غیر ممکن مینماید.به زبان ساده تر کامپایل کردن جهت دریافت نسخه خروجی : یکسری فرایند هایی هستند که با اجرا شدن بترتیب آنها از کدهای ایجاد شده ما نسخه خروجی و فایل نصبی تهیه مینمایند . حال با decompile کردن یا مهندسی معکوس کردن این فرانید (وب سایت های بسیاری هستند که این کار را با یک کلیک انجام میدهند) میتوانند از نسخه خروجی کدهای اپلیکیشن شما را استخراج نمایند . البته این کد ها خوانایی زیادی ندارند ولی اگر در دست decompiler هایی حرفه ای قرار گیرد میتوانند اطلاعات مفیدی از کد هایی شما بدست آورند.چرا ما باید از Proguard و R8 استفاده می نماییم ؟به هنگام ایجاد اپلیکیشن مقدار زیادی از کد و کتابخانه های بلا استفاده و در کد های ما ایجاد می شود که باعث افزایش سایز بسته خروجی اپلیکیشن ما میشود . با فعال نمودن Proguard یا r8 این کد های بلا استفاده حذف شده و کد هایی باقی مانده را بهینه سازی کرده و با تغییر نام کلاس ها ، توابع یا متغیر ها کد ها را بهینه و خوانایی آنها را در هنگام decompile بسیار پایین و حتی غیر ممکن مینماید و امنیت کد ها را به سطح مناسبی میرساند .آشنایی با سه تابع بسیار کارآمد در Proguard یا R8 1-Shrink or tree shaking : کوچک کردن یا لرزش درختیحذف کلاس ها ، فیلد ها و متغیر های بلا استفاده2- code optimization : بهینه سازی کد ها کد ها را در سطح ساختاری کوچک تر و کارامد تر می کند3- identifier renaming : تغییر نام به نام های بی معنادر این مرحله نام کلاس ها ، توابع و متغیر ها با نام های کوتاه و بی معنا تغییر می دهد و از سایز اپلیکیشن کاهش می دهداستفاده از Proguard و R8 چه میزان از حجم نسخه خروجی می تواند کاهش دهد ؟ برای اثبات این موضوع استناد می کنیم به تحقیقاتی که بروی R8 در سال 2019 توسط تیم توسعه دهندگان اندروید summit جهت کاهش سایز بروی یک اپلیکشن ساده اندروید انجام پذیرفت .آنها یک اپلیکیشن ساده که فقط حاوی یک Activity و با زبان kotlin قبل از استفاده از R8 سایز نسخه خروجی 3.444 kb بود و پس از فعال سازی R8 سایز آن به 780 kb کاهش یافت که نتیجه حاصله 2.644 kb بوده که چیزی حدود 70% کمتر از نسخه خروجی قبل از فعال سازی R8 می باشد.سپس همان اپلیکیشن را به همراه کتابخانه okhttp برسی کردند و قبل از فعال بودن R8 سایز آن 4.134kb و پس از فعال کردن R8 خروجی 780kb شد که نتیجه حاصل شده 79% کاهش حجم فایل خروجی بود نحوه فعال نمودن Proguard و R8 در اندروید برای فعال نمودن ، کافیست قطعه کد زیر را در فایل 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هنگامی که ما Proguard یا R8 را فعال مینماییم بطور پیش فرض تمامی سه توابع بروی تمامی کلاس ها و توابع ما فعال می شود ولی گاهی اوقات نیاز است که کلاسی خاص یا توابع یا متغیر هایی خاص مورد استثناء قرار گیرد. برای مثال اگر شما با کتابخانه Gson آشنا باشید ، این کتابخانه وظیفه تبدیل کد های json را به Object ها در اندروید بر عهده دارد .در این کتابخانه نام متغیر های model ارسالی بسیار مهم می باشد و اگر تغییر کند مقدار بازگشتی متغیر ها null خواهد بود . برای جلوگیری از این کار توسط Proguard یا R8 ما مجموعه قوانینی وضع می نماییم که بعضی از کلاس ها , توابع و یا متغیر ها را استثنا قرار دهد .چگونه از Rules ها استفاده نماییم ؟شاید در ابتدا برای شما کمی استفاده از این نوع کد ها بسیار سخت باشد ولی پس از استفاده پی خواهید برد که نوشتن قوانین ساده تر از حد تصور شما خواهد بود keepبا استفاده از این دستور شما میتوانید یک کلاس را مورد استثناء قرار دهید -keep class com.example.Data.Model.user { <fields>; }با استفاد از قوانین بالا ما میتونیم تمام فیلد های کلاس user را استثناء قرار دهیمچند نکته بسیار مهم که باید قبل از بکار گیری Proguard یا R8 حتما باید مورد توجه قرار دهید .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=&quotMusicPlayerFragment"3-Component Classبدلیل اینکه در فایل های Xml ما از کامپوننت ها استفاده میکنیم و اگر نام آنها تغییر کند برنامه در هنگام اجرا به ایراد بر میخورد4-add library rules to Proguardپس از افزودن کتابخانه های توجه کنید که اگر از قوانین خاصی استفاده می کند آن را در فایل proguard-rules.pro اپلیکیشن خود قرار دهید5-dont change native class nameتوجه شود که اگر از کتابخانه های native که با زبان های c++ در اپلیکیشن استفاده می شود در قسمت قوانین پروگارد قرار گیرددوستان عزیز برای تهیه این مقاله بیش از 20 مقاله زبان اصلی مطالعه شد و سعی شد بدیلی اینکه چنین مقاله ای به زبان فارسی در دسترس نبود بصورت خیلی ساده شرح داده شود ممنون بابت اینکه وقت گرانبهاتون را به خوندن این مقاله اختصاص دادین و اگه دوست داشتین لایک کنین و نظر بدین تا از نظرات ارزشمندتون در مقاله های بعدی استفاده کنیم