دوستان با توجه به اینکه این آموزش مربوط به 4 ماه پیش و وقتیه که اولین برنامم رو داشتم مینوشتم
نیاز به این داره که چند تا نکته رو اصلاح و اضافه کنم :
------------------------
برای تست برنامه روی شبیه ساز شما میتونید heap دستگاه رو توی AVD تعیین کنید، heap همون حافظه رم اختصاصی برای هر برنامه ست
خطای OOM معمولا وقتی پیش میاد که heap پایین تر از سطحی باشه که شما دارید عکس رو با اون سایز لود میکنید
مثلا یک عکس با کیفیت رو با اندازه 720*1200 یا بالاتر دارید توی heap با اندازه 32 یا پایین تر لود میکنید
پس خیلی راحت میشه نتیجه گرفت حتی با تغییر سایز عکس پس زمینه توی گوشی هایی که رزولوشن بالا دارن اما هیپ پایین دارن، خطا خواهیم گرفت
توی Genymotion اگر خواستید تست کنید، یک دستگاه با SDK ورژن 2.3 بسازید و رزولوشن 720*1200 و بالاتر
ورژن 2.3 توی geny دارای هیپ 32 هست، تست مناسبی میشه برای خطایابی پرشدن حافظه، اما قابل مقایسه با گوشی نیست
-----------------------
رم اختصاص داده شده به هر برنامه متغیر بین 16 تا 256 مگابایت هست، این مقدار بر اساس ورژن سیستم عامل و مشخصات دستگاه تعیین میشه
اطلاعات رم اختصاص داده شده به برنامه و کلاس هیپ رو با این کد به دست بیارید
Runtime rt = Runtime.getRuntime();
long maxMemory = rt.maxMemory();
ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
int memoryClass = am.getMemoryClass();
Log.d("memory class", "max: " + maxMemory + ", class: " + memoryClass);
می تونید براساس یک آنالیز بین رزولوشن و اندازه هیپ، مقدار مناسب پایین اوردن کیفیت رو به دست بیارید
------------------------
توی یک قسمت من گفتم طول و عرض layout رو برای تغییر اندازه backGround میگیریم
این کار رو نمیشه توی متد onCreate انجام داد، چون توی این متد هنوز اشیاء ساخته نشدن و اگر شما بخواین طول و عرض رو بگیرید مقدار صفر برمیگردونه
اگر layout شما فول اسکرین و بدون اکشن بار و استاتوس بار هست میتونید با استفاده از متریک دستگاه اندازه طول و عرض کل صفحه نمایش رو به دست بیارید
DisplayMetrics metrics = this.getResources().getDisplayMetrics();
width = metrics.widthPixels;
height = metrics.heightPixels;
------------------------
اگر متغیرهای bitmap رو توی متد onStop پاک کنید ( recycle )، امکان داره وقتی دوباره به اکتیویتی برمیگردید با پیام خطا مواجه بشید
بهتره این کار توی متد onDestroy انجام بشه و قبلش شرط بذارید که اگر bitmap مساوی null نبود اون رو recycle کنه
------------------------
متغیر InSampleSize توی تابع CalculateInSampleSize بیانگر درجه پایین اوردن کیفیت عکس و از نوع int هست با مقدار اولیه 1
این مقدار بر اساس یک محاسبه بین اندازه اصلی عکس و اندازه خواسته شده، ممکنه در دو ضرب بشه
اگر شما عدد اولیه رو بذارید 2، ممکنه درجه کیفیت شما برابر 4 بشه
خب مسلما بین کیفیت 2 و 4 تفاوت خیلی زیاد میشه
بهتره شما با انجام یکسری تغییرات یک مقدار از نوع اعشاری رو قرار بدید و توی هر بار خطا گرفتن به اندازه 0.5 واحد بهش اضافه کنید که اگر ضرب در 2 شد، تفاوت بین کیفیت چشمگیر نباشه
مقدار اصلی که برگشت داده میشه حتما باید از نوع int باشه