بهینه سازی مصرف RAM در برنامه نویسی اندروید

در برنامه نویسی اندروید، کار شما با دستگاهی کوچک است که امکانات سخت افزاری محدودی نسبت به یک کامپیوتر یا یک لپتاپ دارد. پردازشهای های سنگینی مثل GUI، و Phone مقداری از حافظه‎ی RAM دستگاهتان را می‎گیرد و شما فضای کم‎تری برای استفاده در برنامه‎ی خود در اختیار دارید.

شاید گوشی‎های قوی امروز با ۳ گیگابایت RAM و پردازنده‎ی ۲٫۳ گیگاهرتز شامل این نگرانی نباشند اما باید در نظر گرفت که برنامه‎ی شما قرار است روی تمام دستگاه‎های اندرویدی (یا حداقل بیشترشان) بدون مشکل اجرا شود.

 

برنامه‎های موفق اندروید معمولا از انیمیشن‎های زیبا و گرافیک کاربرپسندی برخوردارهستند، و استفاده از عکس در جاهای مختلف یک اپلیکیشن خوب، دور از انتظار نیست. اما اگر از دید یک برنامه نویس به ظاهر و کارکرد یک اپلیکیشن موفق نگاه کنیم و یک برنامه‎ی Ram Usage Monitor داشته باشیم، می‎بینیم نهایت اسفاده‎ی آن برنامه از RAM ، به ۵۰ مگابایت هم نمی‎رسد.

در برنامه نویسی اندروید، بعد از طراحی ظاهر برنامه مهم ترین مسئله، استفاده‎ی بهینه از منابع به خصوص حافظه‎ی RAM است. بدون توجه به این مسئله برنامه شما ممکن از کمتر از ۵ دقیقه برای کاربر کار کند و مفید باشد، زیرا بعد از آن یا سرعت برنامه‎تان به شدت پایین می آید یا به علت کمبود بیش از حد RAM، اندروید برنامه شما را می‎بندد (Process آن را Kill می‎کند) بدون توجه به آن که شما در متد onDestroy یا onStop چه چیزهایی نوشته باشید.

چندین المان در برنامه نویسی هستند که از نظر مصرف حافظه‎ی RAM یکی از خط قرمزهای ما محسوب می‎شوند

  • متغیرها و کلاس‎هایی که خودمان طراحی کردیم

کلاس‎هایی که برای خواناتر کردن برنامه تان می‎نویسید احتمالا یکی از چیزهایی ست که باید بعد از اتمام کار، از نظر مصرف RAM بهینه شوند. اگر درون یک حلقه در هر گام، یک شیء از کلاستان می‎سازید بهتر است راه دیگری را برای اجرا کردن آن قطعه کد انتخاب کنید. درست است که Garbage Collector در اندروید بسیار خوب عمل می‎کند و شما لازم نیست نگران کلاس‎هایتان باشید، اما اگر در کلاستان از Bitmap استفاده می‎کنید، اعتماد کردن به GC کمی ریسک محسوب می‎شود.

سعی کنید متغیرهایی با طول زیاد به صورت ایستا (static) تعریف نکنید. منظور از متغیرهایی با طول زیاد، چیزهایی نظیر Bitmap است.

  • عکس

اگر در برنامه‎تان از عکس استفاده می‎کنید (که به احتمال خیلی زیاد استفاده می‎کنید) چه این عکس به صورت یک resource برای برنامه‎تان باشد و چه از اینترنت یا حافظه‎ی داخلی بارگذاری شود، یک خطر بسیار جدی برای برنامه‎تان محسوب می‎شود. عکس ها به طور بی‎رحمانه‎ای RAM مصرف می‎کنند و یکی از اصلی ترین علت خطای out of memory هستند.

سخت ترین کارتان زمانی است که عکس ها را از اینترنت دریافت می‎کنید و در یک لیست نشان می‎دهید، در این حالت نه حجم عکس مشخص است، نه تعداد آیتم‎هایی که کاربر از لیست می‎تواند ببیند (به علت اندازه‎های مختلف صفحه نمایش).

اندازه‎ی عکس‎ها باید قبل از نمایش داده شدن در برنامه‎تان، بسته به ابعاد ImageView (یا هر ابزاری که عکس را با آن نمایش می‎دهید) کمتر شوند. همچنین باید توجه داشت که در این کم شدن ابعاد، تغییر کیفیت محسوس نداشته باشید.

این روییه چند مرحله و چند پیش زمینه می‎خواهد که به طور خلاصه به آن ها اشاره می‎کنیم.

  1. کاربرد پوشه‎ی values در پوشه‎های پروژه‎ی خود را بشناسید و حالت‎های مختلف این پوشه را در اندازه‎های مختلف صفحه نمایش و موقعیت‎های مختلف پیاده سازی کنید. مثلا values-large برای تبلت‎های ۷ و ۸ اینچی و values-fa برای زمانی که زبان برنامه، فارسی است. در این پوشه فایلی به نام dimens.xml وجود دارد که بهتر است برای تعیین ابعاد ابزارهای مختلف از این فایل استفاده کنید
  2. صفحه‎ی مربوط به بارگذاری عکس‎های حجیم را در سایت توسعه دهندگان اندروید بخوانید.
  3. کاربرد متدهای کلاس BitmapFactory را بشناسید. متدهایی برای بارگذاری عکس از اینترنت یا حافظه داخلی گوشی در این کلاس وجود دارند که باعث می‎شوند سر و کار شما به این کلاس زیاد بیفتد.
  4. اگر عکسی جزء resource برنامه شما محسوب می‎شود و در پوشه ی drawable قرار دارد، سعی کنید در صورت امکان نسخه‎های مختلفی از نظر ابعاد برای پوشه‎های drawable-small، drawable-medium و… قرار دهید.

اگر عکستان قرار است از حافظه‎ی داخلی گوشی بارگذاری شود یا عکسی که توسط دوربین گرفته شده است را می‎خواهید نمایش دهید، می‎توانید با داشتن ابعاد ابزار نمایش دهنده‎ی عکس، از متد Bitmap.createScaledBitmap استفاده کنید، این متد طول و عرض درخواستی شما را می‎گیرد و ابعاد عکس داده شده را کاهش (یا افزایش) می‎دهد. اما مشکلی که این متد دارد این است که کیفیت عکس را به شدت پایین می‎آورد. زیرا بدون انجام نگاشت و عملیات پردازش تصویر، فقط ابعاد عکس را کوچک‎تر می‎کند.

راه دیگری برای کاهش ابعاد عکس وجود دارد. برای این کار، در ابتدا باید ابعاد عکس را بگیرید، و با توجه به ابعاد ابزار نمایش دهنده‎ی عکس، متغیر inSampleSize را محاسبه کنید (متدی برای محاسبه در همان صفحه‎ی توسعه دهندگان وجود دارد) برای این کار حتما باید یک شیء از کلاس  BitmapFactory.Options بسازید و متغیر inJustDecodeBounds را true قرار دهید. سپس بعد از محاسبه‎ی inSampleSize با مقدار false برای متغیر inJustDecodeBounds اقدام به بارگذاری عکس کنید. مانند قطعه کد زیر :

BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true;
BitmapFactory.decodeFile(“yourImagePath”, opts);
opts.outHeight; //this is the image Height
opts.outWidth; //this is the Image Width
int inSampleSize = CalculateInSampleSize(opts, myImageViewHeight, myImageViewWidth);
opts.inSampleSize = inSampleSize;
opts.inJustDecodeBounds = false;
Bitmap scaledBitmap = BitmapFactory.decodeFile(“yourImagePath”, opts); //this is scaled down picture

این متغیر یک عدد مجذور ۲ است که کلاس BitmapFactory از آن استفاده می‎کند تا ابعاد عکس شما را تقسیم بر این متغیر کند. به زبان دیگر، اگر inSampleSize عدد ۲ باشد، هر ۴ پیکسل از عکس، به ۱ پیکسل نگاشت می‎شود.

با این روش شما می‎توانید مطمئن باشید که کیفیت عکس پایین نمی‎آید. اما محدودیتی که این روش دارد این است که متغیر inSampleSize حتما بایستی عددی مجذور ۲ باشد، اگر شما عکسی با عرض ۶۵۰ می‎خواهید، ممکن است متغیر inSampleSize با عدد ۲ بتواند عرض را به ۷۰۰ برساند و با عدد ۴، عرض این عکس ۳۵۰ می‎شود؛ که بیش از حد کوچک است.

پس بهترین راه برای آنکه عکس مورد نظر را دقیقا در ابعادی که می‎خواهید دریافت کنید این است که از متغیر inSampleSize و متد createScaledBitmap به طور همزمان استفاده کنید.

 

اما تمام این داستان برای بارگذاری عکس از اینترنت متفاوت است، زیرا قطعا این که یک بار عکس را دریافت کنیم تا فقط ابعاد آن را اندازه بگیریم و برای نمایش آن، یک بار دیگر مجبور باشیم عکس را از سرور بگیریم، اشتباه است.

برای این کار، من از کتابخانه‎های زیادی استفاده کردم و خودم هم اقدام به نوشتن یک کتابخانه برای دریافت عکس از اینترنت کردم. اما بهترین کتابخانه‎ای که با آن کار کردم و از امکاناتش استفاده کردم، Universal Image Loader بود. امکانات زیادی برای کش کردن، تغییر ابعاد عکس در این کتابخانه وجود دارد که به احتمال زیاد در برنامه‎تان مورد استفاده قرار می‎گیرند.


فایلهای ضمیمه
توجه! هیچ فایل ضمیمه ای برای این مطلب یافت نشد

نظرات شما نظر جدید
سایر مقالات این دسته
کار با حالت ActionMode در اندرویدکار با انیمیشن ها قسمت اول ساخت Spalsh Screenساخت انیمیشن به صورت کامل قسمت دومحرکت اسلاید بین اکتیوتی ها با انیمیشن ها +سورسمعرفی انواع پایگاه داده (DataBase)کار با دیتابیس در اندروید قسمت اولساخت toggleButton زیبا و سفارشیکار با دیتابیس در اندروید قسمت دومساخت برنامه رادیوی انلاین+سورسکار با حافظه داخلی در اندرویدساخت برنامه تشخیص صدای فارسی و انگلیسی در اندروید+استفاده از سورس های اندروید استودیو در محیط ایکلیپکار با Switch Button در اندرویدتغییر خودکار تصویر پس زمینه لایه ساخت لیست ویو با قابلیت جستوجوی الفباییدانلود تصویر از ادرس اینترنتی+سورسکار با دیتابیس در اندروید:جستجو در sqlite قسمت 1دانلود نسخه جدید و بروز شده محیط توسعه اندرویدکار با دیتابیس در اندروید:جستجو در sqlite قسمت 2ساخت کتاب برای اندروید بدون برنامه نویسیبهترین زبان برنامه نویسی که میتوانید در 2015 بياموكار با Power Manager در اندرويدساخت اسکرول بار سفارشی+سورسساخت گرید ویو سفارشیساخت پروگرس بار با شمارنده +سورسترسیم یک خط با Canvas+سورستغییر نام برنامه به صورت کاملکار با حالت دوبل بک(Double back)ساخت برنامه دو زبانه(Multi language )ساخت لایه و عناصر داینامیک در اندرویدساخت برنامه چاپ متن بر روی تصویر+سورسکار با ShowCase View در اندروید+سورسافزودن لیست به الرت دیالوگ+سورسساخت مرورگر وب سادهکار با Drag And Drop در اندروید+سورسکار با DatePickerDialog در اندروید+سورسکار با فرگمنت ها(ساخت Sliding Navigation Drawer)کار با ViewFlipper (ساخت اسلاید شو تصاویر)ساخت توست سفارشی قسمت دوم زمانبندی Toastکار با BroadcastReceiver ها،ساخت برنامه دریافتsmsطراحی و ساخت صفحه Login Screen + سورسبارگذاری ویدیو از گالری در اندرویدساخت پنجره پاپ آپ + سورسبارش برف بروی تصویر + سورسکار با فیلتر hue رنگی کردن تصویر انتخاب و پخش فایل صوتی از حافظه گوشی+سورساضافه کردن چک باکس به لیست ویوکار با ShelfView یا نمایش کتابخانه ای + سورسکار با TabHost،اضافه کردن تب به برنامه های اندرویدمعکوس کردن رنگ ها(Invert Image) + سورسآموزش کامل ساخت اکشن بار سفارشی+سورسساخت برنامه های واکنش گرا(ریسپانسیو) در اندرویدقسمت دوم صفحات 7 اینچ به بالااضافه کردن انیمیشن به دکمه+سورسکار با View Switcher در اندروید + سورسکار با فیلتر Blur Mask + سورسدانلود پک کامل آیکون های طراحی اندرویدکار با sharedPreferences در اندروید+سورسآموزش کار با proguard،محافظت از برنامه اندرویدپخش فایل صوتی (MP3) از ادرس اینترنتی+سورسپخش ویدیو از آدرس اینترنتی(URL) در اندروید+سورسگوشی های و تبلت های مطرح تا چینی به ساده ترین روشپاسخ به رویداد های WebVeiw دسترسی به وب ویو با استفاده از جاوااسکریپتکار با WIFI اکسس+سورسساخت تقویم هجری برای اندروید+سورسapp rateدانلود و نمایش تصویر در ListView+سورسدانلود و نمایش فایل متنی+سورسکار با کلاس های پایه اکتیویتیآینه کردن تصویر+سورسافزودن آیتم منو سفارشی بهActionBar+سورسارسال اطلاعات از دیتابیس به GridView + سورسکار با کلید های فیزیکی در اندروید+سورسدسترسی به Api هایREST قسمت اولتغییر فونت لیست ویواستفاده از تحلیل گرGoogle Analytics در برنامه اندرویداضافه کردن انیمیشن به دیالوگ ها در اندروید+سورساستفاده ازگیت‌هاب در اندروید استودیوکار با Swipe tab Layouدر برنامه نویسی اندروید دیباگ کردن برنامه اندروید با wifiبهینه سازی مصرف RAM در برنامه نویسی اندرویدافزودن شمارنده صفحه به ViewPager + سورس آموزش نرم افزار SQLite Browserکار با JSON در اندرویدآموزش ساده نصب شبیه ساز اندروید Genymotion