Garbage Collection
Garbage Collection چیست؟؟؟
کلاسهایی که برای خواناتر کردن برنامه تان مینویسید احتمالا یکی از چیزهایی ست که باید بعد از اتمام کار، از نظر مصرف RAM بهینه شوند. اگر درون یک حلقه در هر گام، یک شیء از کلاستان میسازید بهتر است راه دیگری را برای اجرا کردن آن قطعه کد انتخاب کنید. درست است که Garbage Collector در اندروید بسیار خوب عمل میکند و شما لازم نیست نگران کلاسهایتان باشید، اما اگر در کلاستان از Bitmap استفاده میکنید، اعتماد کردن به GC کمی ریسک محسوب میشود.
اگر در برنامهتان از عکس استفاده میکنید (که به احتمال خیلی زیاد استفاده میکنید) چه این عکس به صورت یک resource برای برنامهتان باشد و چه از اینترنت یا حافظهی داخلی بارگذاری شود، یک خطر بسیار جدی برای برنامهتان محسوب میشود. عکس ها به طور بیرحمانهای RAM مصرف میکنند و یکی از اصلی ترین علت خطای out of memory هستند.
سخت ترین کارتان زمانی است که عکس ها را از اینترنت دریافت میکنید و در یک لیست نشان میدهید، در این حالت نه حجم عکس مشخص است، نه تعداد آیتمهایی که کاربر از لیست میتواند ببیند (به علت اندازههای مختلف صفحه نمایش).
اندازهی عکسها باید قبل از نمایش داده شدن در برنامهتان، بسته به ابعاد ImageView (یا هر ابزاری که عکس را با آن نمایش میدهید) کمتر شوند. همچنین باید توجه داشت که در این کم شدن ابعاد، تغییر کیفیت محسوس نداشته باشید.
این روییه چند مرحله و چند پیش زمینه میخواهد که به طور خلاصه به آن ها اشاره میکنیم.
- کاربرد پوشهی values در پوشههای پروژهی خود را بشناسید و حالتهای مختلف این پوشه را در اندازههای مختلف صفحه نمایش و موقعیتهای مختلف پیاده سازی کنید. مثلا values-large برای تبلتهای 7 و 8 اینچی و values-fa برای زمانی که زبان برنامه، فارسی است. در این پوشه فایلی به نام dimens.xml وجود دارد که بهتر است برای تعیین ابعاد ابزارهای مختلف از این فایل استفاده کنید
- صفحهی مربوط به بارگذاری عکسهای حجیم را در سایت توسعه دهندگان اندروید بخوانید.
- کاربرد متدهای کلاس BitmapFactory را بشناسید. متدهایی برای بارگذاری عکس از اینترنت یا حافظه داخلی گوشی در این کلاس وجود دارند که باعث میشوند سر و کار شما به این کلاس زیاد بیفتد.
- اگر عکسی جزء 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
با این روش شما میتوانید مطمئن باشید که کیفیت عکس پایین نمیآید. اما محدودیتی که این روش دارد این است که متغیر inSampleSize حتما بایستی عددی مجذور 2 باشد، اگر شما عکسی با عرض 650 میخواهید، ممکن است متغیر inSampleSize با عدد 2 بتواند عرض را به 700 برساند و با عدد 4، عرض این عکس 350 میشود؛ که بیش از حد کوچک است.
پس بهترین راه برای آنکه عکس مورد نظر را دقیقا در ابعادی که میخواهید دریافت کنید این است که از متغیر inSampleSize و متد createScaledBitmap به طور همزمان استفاده کنید.
آموزش اندروید آموزش برنامه نویسی اندروید برنامه نویسی اندروید اندروید استودیو آموزش اندروید استودیو