Android out of memory hatası

Android için uygulama geliştirirken yüksek çözünürlüklü resimlerle çalıştığımızda out of memory hatası ile karşılaşabiliriz.

03-21 21:45:44.255: E/dalvikvm-heap(353): 4423680-byte external allocation too large for this process.
03-21 21:45:44.345: E/GraphicsJNI(353): VM won't let us allocate 4423680 bytes

Bu durumdan kurtulmak için developer sayfasında anlatılan yöntemi kullanabilirsiniz.

Örnek olarak kendi kullandığım class ı burada paylaşıyorum.

bitmapHelper.java

package com.defter.org;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

public class bitmapHelper {

	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) {

        // Calculate ratios of height and width to requested height and width
        final int heightRatio = Math.round((float) height / (float) reqHeight);
        final int widthRatio = Math.round((float) width / (float) reqWidth);

        // Choose the smallest ratio as inSampleSize value, this will guarantee
        // a final image with both dimensions larger than or equal to the
        // requested height and width.
        inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
    }

    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);
    }
}

örnek kullanım

mImageView.setImageBitmap(
    decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100));

ImageAdapter den kullanım örneği

imageView.setImageBitmap(bitmapHelper.decodeSampledBitmapFromResource (mContext.getResources(), mThumbIds[position], width, height));

width ve height tanımını istediğimiz boyuta göre yapıyoruz.

Android out of memory hatası” için 8 yorum

  • 17 Mayıs 2013 tarihinde, saat 16:05
    Permalink

    Kardeş ben imageswitcherde nasıl kullanabilirim 2 saattir deniyorum yapamadım haftaya son ödev teslimi yardım lütfenn

    Yanıtla
    • 17 Mayıs 2013 tarihinde, saat 16:55
      Permalink

      ImageSwitcher.setImageBitmap(bitmapHelper.decodeSampledBitmapFromResource(getResources(), R.id.imajiniz, 100, 100));

      şeklinde olmuyormu?

      Aldığınız hatayı da yazarsanız ona göre bakarız.

      Yanıtla
      • 17 Mayıs 2013 tarihinde, saat 17:15
        Permalink

        imageswitcherin setImageBitmap metodu yok malesef altını çiziyor.

        iSwitcher.setImageResource(pics[ImageNo]); // benim yapmak istediğim bu ama boyut fazla olunca outofmemory hatası veriyor.

        iSwitcheri geçtim yukarıdakini deniyorum aynı fotolarla yine aynı hatayı veriyo,
        imageViewin fotosunu nasıl değiştircez burda

        mimageView.setImageBitmap(decodeSampledBitmapFromResource(getResources(), R.id.imageView1, 720, 1200));

        getresource kısmından devam ediyorum getdrawable diye felan ama olmuyo

        Yanıtla
        • 18 Mayıs 2013 tarihinde, saat 01:07
          Permalink

          ImageAdapter de

          imageView.setImageBitmap(bitmapHelper.decodeSampledBitmapFromResource (mContext.getResources(), mThumbIds[position], width, height));

          şeklinde kullanın.

          imageSwitcher da ise

          Drawable drawable =new BitmapDrawable(bitmapHelper.decodeSampledBitmapFromResource (mContext.getResources(), mThumbIds[position], width, height));
          imageSwitcher.setImageDrawable(drawable);

          şeklinde kullanın. Sorun çıkmıyor.

          Yanıtla
          • 18 Mayıs 2013 tarihinde, saat 06:06
            Permalink

            ilginiz için teşekkür ederim dediğiniz gibi yaptım width, height değerlerini düşük girersem 200 e 200 gibi hata vermiyo ama bana daha yüksek lazım. bu sınıf sadece fotoların boyutunumu azaltıyor acaba? manuel olarakta yapılır o aslında… kafa uctu benim yatıyım biraz 🙂

  • 19 Mayıs 2013 tarihinde, saat 15:17
    Permalink

    public class GalleryView extends Activity implements ViewFactory {

    String foto[] = {
    “foto1.jpg”,
    “foto2.jpg”,
    “foto3.jpg”,
    “foto4.jpg”,
    “foto5.jpg”,
    “a.jpg”,
    “foto6.jpg”,
    “foto7.jpg”,
    “foto_1.jpg”,
    “foto_2.jpg”,
    “foto_3.jpg”,
    “foto_4.jpg”,
    “foto_5.jpg”,
    “foto_6.jpg”,
    “foto_7.jpg”,
    “foto_8.jpg”,
    “foto_9.jpg”,
    “foto_10.jpg”,
    “foto_11.jpg”,
    “foto_12.jpg”,
    “foto_13.jpg”,
    “foto_14.jpg”,
    “foto_15.jpg”,
    “foto_17.jpg”,
    “foto_18.jpg”,
    “foto_19.jpg”,
    “foto_20.jpg”,
    “foto_21.jpg”,
    “foto_22.jpg”,
    “foto_23.jpg”,
    “foto_24.jpg”,
    “foto_25.jpg”,
    “foto_26.jpg”,
    “foto_27.jpg”,
    “foto_28.jpg”,
    “foto_29.jpg”,
    “foto_30.jpg”,
    “foto_31.jpg”,
    “foto_32.jpg”,
    “foto_33.jpg”,
    “foto_34.jpg”,
    “foto_35.jpg”,
    “foto_36.jpg”,
    “foto_37.jpg”,
    “foto_38.jpg”,
    “foto_39.jpg”,
    “foto_40.jpg”,
    };
    ImageSwitcher iSwitcher;
    Bitmap b = null;

    int i=0;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    iSwitcher = (ImageSwitcher) findViewById(R.id.imageSwitcher1);

    //fotoların fade in-out animasyonu
    iSwitcher.setFactory(this);
    iSwitcher.setInAnimation(AnimationUtils.loadAnimation(this,
    R.anim.slide_in_left));
    iSwitcher.setOutAnimation(AnimationUtils.loadAnimation(this,
    R.anim.slide_out_left));

    final Timer t = new Timer();
    final Handler handler = new Handler();

    TimerTask fotoZamanlama;
    try {

    fotoZamanlama = new TimerTask() {
    public void run() {
    handler.post(new Runnable() {
    public void run() {
    try{

    try {
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inPurgeable = true;
    AssetManager assets = getResources().getAssets();
    Bitmap bitmap = BitmapFactory.decodeStream(assets.open(foto[i]), null, options);
    if(bitmap == null) {
    throw new IOException(“File cannot be opened: It’s value is null”);
    }
    else {

    }

    Drawable drawable =new BitmapDrawable(bitmap);
    iSwitcher.setImageDrawable(drawable);

    } catch (IOException e) {
    throw new IOException(“File cannot be opened: ” + e.getMessage());
    }
    i++;
    }catch (Exception e) {
    Toast.makeText(getBaseContext(), e.getMessage(),
    Toast.LENGTH_SHORT).show();
    }

    }
    });
    }
    };

    t.schedule(fotoZamanlama, 0, 1000);
    } catch (Exception hata) {
    Toast.makeText(getBaseContext(), hata.getMessage(),
    Toast.LENGTH_SHORT).show();
    }

    }

    @Override
    public View makeView() {
    // TODO Auto-generated method stub
    ImageView i = new ImageView(this);
    i.setBackgroundColor(0xFFFFFF);
    i.setScaleType(ImageView.ScaleType.FIT_XY);
    i.setLayoutParams(new ImageSwitcher.LayoutParams(LayoutParams.FILL_PARENT,
    LayoutParams.FILL_PARENT));
    return i;
    }
    }

    // 2 gündür araştırma sonucu bu kodu toparladım ve oldu sonunda. ister 10 Kb ister 10 Mb foto yükle tak diye açıyor hemde imageSwitcher ile 😀

    Yanıtla
  • 06 Kasım 2013 tarihinde, saat 03:56
    Permalink

    Hocam ben bunu public View getView(int position, View convertView, ViewGroup parent) {

    ImageView imageView = new ImageView(mContext);
    imageView.setLayoutParams(new Gallery.LayoutParams(150, 100));
    imageView.setScaleType(ImageView.ScaleType.FIT_XY);
    imageView.setBackgroundResource(mGalleryItemBackground);
    imageView.setPadding(8,8,8,8);
    Drawable d = null;
    try {
    d = Drawable.createFromStream(mContext.getAssets().open(names[position]), null);
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    imageView.setBackgroundDrawable(d);
    //imageView.setImageDrawable(d);
    return imageView;
    }

    şeklindeki yerde nasıl kullanabilirim birde hocam emeğinize sağlık gayet güzel anlatım olmuş ama anlamadığım nokta BitmapFactory.decodeResource(res, resId, options); gibi yerlerde resi resId gibi kullanımların değişmesi gerekiyormu.Ben galeri yapımında kullandım assetden çekerek ama sayfada tekrar geri gelice out of memory hatası yiyorum.Hayatı da decodeStream olarak gösteriyor.Bu kullanımlar sizce yeterlimi.Birde hocam Resources res gibi yerleri nasıl değiştimemiz gerekiyor.Yardımlarınız için teşekkürler kolay gelsin çalışmalrınızda.

    Yanıtla
  • 25 Ekim 2014 tarihinde, saat 12:44
    Permalink

    Vedat bey merhabalar android studioda imageSwitcher ile hata almıyorum ama bazı cihazlarda bu hatadan muzdaribim son satırında olabilceğini düşünüyorum sorunun
    @Override
    public View makeView() {
    ImageView i = new ImageView(this);
    i.setScaleType(ImageView.ScaleType.FIT_XY);

    return i;

    }
    son satırım bu şekilde FIT_XY sorun olabilir mi ?
    xml dosyasında FILL_PARENT olarak kayıtlı gösterim
    teşekkürler

    Yanıtla

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir