نمایش نتایج 1 تا 16 از 16

نام تاپیک: آموزش : حل خطای Out of Memory و Force Close هنگام کار با عکس ها (Bitmap)

  1. #1

    آموزش : حل خطای Out of Memory و Force Close هنگام کار با عکس ها (Bitmap)

    سلام دوستان

    من بالاخره مشکلم رو حل کردم ، به همین مناسبت گفتم زکات علمم رو بدم و واسه کسایی که احیانا در آینده دچار مشکل من میشن ، توضیح بدم تا نخوان مثل من 2 روز کامل کل اینترنت رو بگردن

    ابتدا بذارین یه توضیح بدم که خطای OOM یا همون Out Of Memory به چه دلیل رخ میده
    سیستم عامل اندروید برای اجرای هر برنامه ، مقدار محدودی از حافظه رم رو در اختیار اون برنامه میذاره که متناسب با نوع دستگاه ، بین 16 تا 128 مگابایت هست
    این حافظه کم ، وقتی که عکس های با اندازه بالا رو توی خودش لود میکنه ، به سرعت پر میشه ، به همین دلیل برنامه force close میده و اگر توی log سیستم ببینید ، هنگام کار با عکس ها یا setContentView می تونید خطای OOM رو ببینید
    البته میدونید که force close دلایل متعددی داره ، و این تنها یکی از دلایلش هست

    خب من برای رفع مشکلم چکار کردم ؟؟؟ اومدم چند تا حرکت زدم
    حرکت اول اینکه توی هیچ فایل xml عکسی رو لود نکردم از resource
    حرکت دوم ، توی متد onCreate هر اکتیویتی اومدم عکس ها رو لود کردم و قرار دادم
    خب تا اینجای کار شما بازم ارور میگیرید ، پس عملا کاری نکردین ، بنابراین قسمتی که مهمه کوچیک کردن عکس های بزرگ هست
    پس حرکت سوم اینه که شما با استفاده از دو تا تابع که سایت اندروید داده واسه کار کردن با bitmap های بزرگ ، عکس هاتون رو در اندازه مناسب کوچیک کنید
    حالا چند تا ابهام هست ، اینکه گوشی های مختلف سایز های مختلف دارن ، و شما نمیدونید اندازه مناسب برای کوچیک کردن عکس چیه
    من چون توی برنامه با عرض و طول صفحه زیاد کار دارم ، یک راه حل ساده دارم
    توی اکتیویتی splash screen هنگام خروج میام عرض و طول layout رو توی یک کلاس عمومی ذخیره میکنم
    حالا روی اینا مانور نمیدم چون طولانی میشه ...

    خب اگر تعداد اکتیویتی هاتون زیاد هست ، این دو تا تابع رو توی یک کلاس جدا به اسم Module بنویسین که استفاده از اونها راحت تر باشه

    public static int calculateInSampleSize(
    BitmapFactory.Options options, int reqWidth, int reqHeight) {
    // Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {

    final int halfHeight = height / 2;
    final int halfWidth = width / 2;

    // Calculate the largest inSampleSize value that is a power of 2 and keeps both
    // height and width larger than the requested height and width.
    while ((halfHeight / inSampleSize) > reqHeight
    && (halfWidth / inSampleSize) > reqWidth) {
    inSampleSize *= 2;
    }
    }

    return inSampleSize;
    }


    public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
    int reqWidth, int reqHeight) {

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeResource(res, resId, options);
    }


    خب حالا با استفاده از تابع decodeSampledBitmapFromResource می تونید عکس ها رو کوچیک کنید
    یک مثال میزنم برای ست کردن بک گراند یک layout

    Bitmap b = module.decodeSampledBitmapFromResource(getResource  s(), R.drawable.reading_page, 480, 800);
    readingPage = (LinearLayout) findViewById(R.id.readingPage);
    readingPage.setBackgroundDrawable((BitmapDrawable) new BitmapDrawable(b));


    خب الان عکستون به اندازه 480*800 کوچیک شد و ست شد
    اگر باز هم ارور گرفتید توی این قسمت ، باید کیفیت عکس رو پایینتر بیارید
    برای این کار توی تابع calculateInSampleSize که بالا نوشتم ، مقدار اولیه inSampleSize رو یکی اضافه کنید ، اگر باز هم ارور گرفتید مقدار رو به 3 تغییر بدید تا کیفیت به حداقل برسه ( من با مقدار 1 ارور میگرفتم )

    خب تا اینجا شما عکس رو کوچیک کردید و ست کردین
    برای احتیاط و اینکه هر وقت حافظه رو لازم نداشتین بتونین آزاد کنین ، انجام چند تا کار ضروری هست
    اول اینکه متغیرهای Bitmap رو عمومی تعریف کنید
    دوم در متد onStop هر اکتیویتی ، عکس تمام اشیاء و layout رو null کنید
    فقط حواستون باشه که توی متد onRestart باید دوباره عکس اشیاء و layout رو مقدار بدین
    سوم ، توی متد onStop تمام متغییر های Bitmap رو recycle کنید
    b.Recycle();


    کار تمومه ، دیگه خطای out of memory نخواهید گرفت

    حالا موضوع دیگه اینکه ، شاید شما نخواین همیشه کیفیت و اندازه عکس رو بیارین پایین
    راه حل خیلی ساده اینه که اول از راه معمولی عکس بک گراند یا هرچیزی رو ست کنید ، بعد اگر خطای OOM گرفتید با استفاده از try catch حالا مجبور هستید که کیفیت عکس رو بیارید پایین
    بالاخره بهتر از کرش کردن برنامه هست
    اینم یک نمونه کد برای این قسمت آخر
    		try {
    readingPage.setBackgroundResource(R.drawable.readi ng_page);
    } catch (OutOfMemoryError e) {
    Bitmap b = module.decodeSampledBitmapFromResource(getResource s(), R.drawable.reading_page, 480, 800);
    readingPage.setBackgroundDrawable((BitmapDrawable) new BitmapDrawable(b));
    }


    دهنم کف کرد دیگه ، آموزش نوشتن هم انصافا سخته
    موفق باشید

  2. #2
    کاربر دائمی آواتار hosseinaryai
    تاریخ عضویت
    مهر 1391
    محل زندگی
    بابل
    پست
    333

    نقل قول: آموزش : حل خطای Out of Memory و Force Close هنگام کار با عکس ها (Bitmap)

    اوووممم خب حالا اگه بخوایم عکسی از توی sdcard بهش معرفی کنیم باید چیکار کنیم ؟

  3. #3

    نقل قول: آموزش : حل خطای Out of Memory و Force Close هنگام کار با عکس ها (Bitmap)

    نقل قول نوشته شده توسط hosseinaryai مشاهده تاپیک
    اوووممم خب حالا اگه بخوایم عکسی از توی sdcard بهش معرفی کنیم باید چیکار کنیم ؟
    اوووومممم

    عرضم به حضورتون توی تابع decodeSampleBitmapFrom... دو جا شما دارید از دستور bitmapFactory.decode استفاده میکنید

    یک جا خط سوم تابع، و یک جا آخر تابع که bitmap رو return میکنید

    این دو تا خط رو با این کد تعویض کنیم

    BitmapFactory.decodeFile("pathName", options);


    البته باید قبلش مسیر عکس رو بدید مسلما

  4. #4
    کاربر دائمی آواتار hosseinaryai
    تاریخ عضویت
    مهر 1391
    محل زندگی
    بابل
    پست
    333

    نقل قول: آموزش : حل خطای Out of Memory و Force Close هنگام کار با عکس ها (Bitmap)

    نقل قول نوشته شده توسط poorman مشاهده تاپیک
    اوووومممم

    عرضم به حضورتون توی تابع decodeSampleBitmapFrom... دو جا شما دارید از دستور bitmapFactory.decode استفاده میکنید

    یک جا خط سوم تابع، و یک جا آخر تابع که bitmap رو return میکنید

    این دو تا خط رو با این کد تعویض کنیم

    BitmapFactory.decodeFile("pathName", options);


    البته باید قبلش مسیر عکس رو بدید مسلما
    اوووممم
    خب باید بگم خیلی ممنون .. کارمو راه انداخت

  5. #5

    نقل قول: آموزش : حل خطای Out of Memory و Force Close هنگام کار با عکس ها (Bitmap)

    دوستان با توجه به اینکه این آموزش مربوط به 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 باشه
    آخرین ویرایش به وسیله poorman : پنج شنبه 05 تیر 1393 در 20:00 عصر

  6. #6
    کاربر دائمی آواتار roohola2434
    تاریخ عضویت
    بهمن 1391
    محل زندگی
    هرمزگان
    پست
    115

    نقل قول: آموزش : حل خطای Out of Memory و Force Close هنگام کار با عکس ها (Bitmap)

    عرض سلام و خستع نباشید و تشکر از زحمات فراوان
    من یک لیست ویو ساختم که بعد شش هفت بار بالا و پایین شدن oom میده
    لیست ویو من کستومه و توش هم عکس داره هم متن
    اولش خوبه کم کم سرعتش کم میشه تا این که از برنامه خارج میشه

  7. #7
    کاربر دائمی آواتار roohola2434
    تاریخ عضویت
    بهمن 1391
    محل زندگی
    هرمزگان
    پست
    115

    نقل قول: آموزش : حل خطای Out of Memory و Force Close هنگام کار با عکس ها (Bitmap)

    نمیشه به جای این کارا بیایم اضافه های حافظه رم رو پاک کنیم؟

  8. #8

    نقل قول: آموزش : حل خطای Out of Memory و Force Close هنگام کار با عکس ها (Bitmap)

    نقل قول نوشته شده توسط roohola2434 مشاهده تاپیک
    نمیشه به جای این کارا بیایم اضافه های حافظه رم رو پاک کنیم؟
    سلام

    والا من با این مورد خیلی کلنجار رفتم، ولی فعلا راهی غیر از کم کردن اندازه و کیفیت عکس پیدا نکردم

    یه سری راهکارهای دیگه توی فروم های مختلف ذکر شده بود اما یا توضیح کافی در موردشون نبود یا از طرف دیگران رد شده بود

    -----------------

    برای مشکل شما که میگید توی لیست ویو دارید نمایش میدید، احتمالا سایز عکس هاتون بزرگه

    سایز و کیفیت عکس رو کم کنید تا این مشکل حل بشه

    اگر مثلا میخواین بعدا اون عکس رو بزرگ نمایش بدید، عکسها رو در دو سایز کوچیک و بزرگ قرار بدید، توی لیست ویو عکس های کوچیک رو نمایش بدید و وقتی کلیک شد عکس بزرگ

    از توابعی هم که معرفی کردم میتونید برای کنترل خطای OOM در حین اجرای برنامه استفاده کنید

  9. #9
    کاربر دائمی آواتار roohola2434
    تاریخ عضویت
    بهمن 1391
    محل زندگی
    هرمزگان
    پست
    115

    نقل قول: آموزش : حل خطای Out of Memory و Force Close هنگام کار با عکس ها (Bitmap)

    این هایی که میفرمایین همه درست اما مال من کل ایتم ها رو میسازه و مشکلی نداره اما بعد چند بار بالا و پایین کردن لیس ویو ارور out of memory میده
    احساس میکنم با بالا و پایین کردن لیست ویو ایتم هاشو دوباره میسازه و روی هم جمع میکنه
    نمیشه ایتم هایی که از صفحه خارج شدن رو حذف کرد؟

  10. #10

    نقل قول: آموزش : حل خطای Out of Memory و Force Close هنگام کار با عکس ها (Bitmap)

    ببینید شما وقتی مثلا 100 تا آیتم دارید و همشون عکس هستن، امکان داره همون اول کرش نکنه، چون 100 تا آیتم رو با هم نمیسازه، فقط همون 4-5 تای اول رو میسازه و برای هر اسکرول آیتم های بعدی که قراره نمایش داده بشن ساخته میشه

    خود اندروید آیتم هایی که از صفحه خارج میشن رو حذف میکنه و تا نیاز نباشه آیتمی رو نمایش بده اون رو نمیسازه توی لیست ویو

    کار ساخت توی getView آداپتر انجام میشه، اما کار حذف دست ما نیست و نمیدونم آیا از حافظه هم پاک میکنه یا نه

    یعنی اگر دقت کنید هر بار که اسکرول میکنید ( بالا یا پایین ) متد getView برای آیتم هایی که میان توی صفحه اجرا میشه

    من همین الان یک جستجو زدم و با این لایبری آشنا شدم Android Universal Image Loader

    https://github.com/nostra13/Android-Universal-Image-Loader

    هنوز باهاش کار نکردم، اما ظاهرا که خیلی کارایی داره، میتونید نمونه کدهاش رو بگیرید و طریقه استفادش رو یاد بگیرید

    کار خاصی نداره، یک فایل jar رو میذارید توی libs و دو تا پرمیشن باید اضافه کنید و بعد از لایبری استفاده کنید

  11. #11
    کاربر دائمی آواتار ho3ein.3ven
    تاریخ عضویت
    آذر 1390
    محل زندگی
    بوشهر
    پست
    1,185

    نقل قول: آموزش : حل خطای Out of Memory و Force Close هنگام کار با عکس ها (Bitmap)

    نقل قول نوشته شده توسط roohola2434 مشاهده تاپیک
    عرض سلام و خستع نباشید و تشکر از زحمات فراوان
    من یک لیست ویو ساختم که بعد شش هفت بار بالا و پایین شدن oom میده
    لیست ویو من کستومه و توش هم عکس داره هم متن
    اولش خوبه کم کم سرعتش کم میشه تا این که از برنامه خارج میشه

    سلام منم چند وقت پیش همین مشکل رو داشتم .

    مشکل از getView آداپترت هست .

    یک سرچ بزن سورس یه custom listview درست رو بگیر.

  12. #12
    کاربر دائمی آواتار roohola2434
    تاریخ عضویت
    بهمن 1391
    محل زندگی
    هرمزگان
    پست
    115

    نقل قول: آموزش : حل خطای Out of Memory و Force Close هنگام کار با عکس ها (Bitmap)

    اره فک کنم حق با شماست
    من از روی اموزش http://androidcode.ir/post/custom-list ساختم
    فک کنم اموزشش مبدتیه و مشکل oom داره
    یه مثال دیگه دیدم تو اینترنت ولی سردرنیاوردم
    اگه راهنماییم کنید ممنون میشم

  13. #13
    کاربر دائمی آواتار ho3ein.3ven
    تاریخ عضویت
    آذر 1390
    محل زندگی
    بوشهر
    پست
    1,185

    نقل قول: آموزش : حل خطای Out of Memory و Force Close هنگام کار با عکس ها (Bitmap)

    از این سورس استفاده کن :

    http://androidexample.com/How_To_Cre...aid=67&aaid=92

  14. #14
    کاربر دائمی آواتار roohola2434
    تاریخ عضویت
    بهمن 1391
    محل زندگی
    هرمزگان
    پست
    115

    نقل قول: آموزش : حل خطای Out of Memory و Force Close هنگام کار با عکس ها (Bitmap)

    ممنون نگاش کردم کلی روش فک کردم ولب متوجه نشدم
    فک کنم هنوز زوده برام
    فقط اگه میشه بگین چی بخونم میتونم اینا رو بفهمم؟

  15. #15
    کاربر دائمی آواتار ho3ein.3ven
    تاریخ عضویت
    آذر 1390
    محل زندگی
    بوشهر
    پست
    1,185

    نقل قول: آموزش : حل خطای Out of Memory و Force Close هنگام کار با عکس ها (Bitmap)

    سورسش رو دانلود کن کاملا معلومه

  16. #16

    نقل قول: آموزش : حل خطای Out of Memory و Force Close هنگام کار با عکس ها (Bitmap)

    نقل قول نوشته شده توسط roohola2434 مشاهده تاپیک
    ممنون نگاش کردم کلی روش فک کردم ولب متوجه نشدم
    فک کنم هنوز زوده برام
    فقط اگه میشه بگین چی بخونم میتونم اینا رو بفهمم؟
    سلام دوستان
    داخل سایت زیر مطلب مفیدی درباره با این خطا و روش پیداکردن و برطرف کردنش نوشته
    http://androidgate.ir/165/fixing-mem...ofmemoryerror/

تاپیک های مشابه

  1. خطای out of memory
    نوشته شده توسط hosein320 در بخش VB.NET
    پاسخ: 6
    آخرین پست: دوشنبه 09 اردیبهشت 1392, 17:10 عصر
  2. سوال: مشکل با خطای out of memory
    نوشته شده توسط oliya24 در بخش VB.NET
    پاسخ: 0
    آخرین پست: چهارشنبه 11 آبان 1390, 16:43 عصر
  3. خطای Out of Memory
    نوشته شده توسط fazelm در بخش برنامه نویسی در 6 VB
    پاسخ: 3
    آخرین پست: شنبه 29 خرداد 1389, 17:24 عصر
  4. خطای out of memory while expanding memory stream
    نوشته شده توسط m-khorsandi در بخش برنامه نویسی در Delphi
    پاسخ: 9
    آخرین پست: چهارشنبه 05 دی 1386, 15:21 عصر
  5. دلیل خطای Out of memory
    نوشته شده توسط Hossein Moradi در بخش برنامه نویسی در 6 VB
    پاسخ: 5
    آخرین پست: یک شنبه 14 اسفند 1384, 22:50 عصر

قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •