1

I am trying to load all the images in image view but after 12 images the application crashes with out of memory

I tried to recycle the bitmap but it fails with unable to reuse bitmap canvas

Here is my code

public void LoadImageArray() {
        Bitmap mybitmap;
        LinearLayout layout = (LinearLayout) findViewById(R.id.image_container);
        //LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(100,100);
        String path= Environment.getExternalStorageDirectory().toString()+"/Pictures";
        File f=new File(path);
        File file[]=f.listFiles();
        BitmapFactory.Options options=new BitmapFactory.Options();
        for (int i = 0; i < 13; i++) {
            layoutParams.setMargins(1, 1, 1, 1);
            layoutParams.gravity = Gravity.LEFT;
            ImageView imageView = new ImageView(this);

            int imageHeight = options.outHeight;
            int imageWidth = options.outWidth;

            String imageType=options.outMimeType;
            if(imageWidth > imageHeight) {
                options.inSampleSize = calculateInSampleSize(options,100,100);//if landscape
            } else{
                options.inSampleSize = calculateInSampleSize(options,100,100);//if portrait
            }
            options.inJustDecodeBounds = false;
            //Bitmap
            try {
                File efile=new File(file[i].getAbsolutePath());
                if(efile.exists()) {
                    mybitmap = BitmapFactory.decodeFile(file[i].getAbsolutePath(), options);


                    imageView.setLayoutParams(layoutParams);
                    imageView.setImageBitmap(mybitmap);
                    imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
                    imageView.setPadding(1, 1, 1, 1);
                    imageView.setColorFilter(34);
                    imageView.setClickable(true);

                    if (mybitmap != null) {
                        layout.addView(imageView);
                       // if (!((BitmapDrawable) imageView.getDrawable()).getBitmap().isRecycled()) {
                       //     ((BitmapDrawable) imageView.getDrawable()).getBitmap().recycle();
                      //  }
                    }
                    //else {layout.addView(imageView);}
                    Log.d("Files", file[i].getName());              
                }
            } catch(Exception e) {Log.d("TAG","Error is " +e);}
        }
    }
Robin Chander
  • 7,225
  • 3
  • 28
  • 42
go sgenq
  • 313
  • 3
  • 13

3 Answers3

0

your not using the options correctly first you make options then set inJustDecodeBounds to true then call decode file on it then you do the rest how you have it, but use these in a row right after you make your options like this

public void LoadImageArray() {
    Bitmap mybitmap;
    LinearLayout layout = (LinearLayout) findViewById(R.id.image_container);
    //LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
    LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(100,100);
    String path= Environment.getExternalStorageDirectory().toString()+"/Pictures";
    File f=new File(path);
    File file[]=f.listFiles();

    for (int i = 0; i < 13; i++) {
         BitmapFactory.Options options = new BitmapFactory.Options();
         options.inJustDecodeBounds = true;
         BitmapFactory.decodeFile(file[i].getAbsolutePath(), options);

        layoutParams.setMargins(1, 1, 1, 1);
        layoutParams.gravity = Gravity.LEFT;
        ImageView imageView = new ImageView(this);

        int imageHeight = options.outHeight;
        int imageWidth = options.outWidth;

        String imageType=options.outMimeType;
        if(imageWidth > imageHeight) {
            options.inSampleSize = calculateInSampleSize(options,100,100);//if landscape
        } else{
            options.inSampleSize = calculateInSampleSize(options,100,100);//if portrait
        }
        options.inJustDecodeBounds = false;
        //Bitmap
        try {
            File efile=new File(file[i].getAbsolutePath());
            if(efile.exists()) {
                mybitmap = BitmapFactory.decodeFile(file[i].getAbsolutePath(), options);


                imageView.setLayoutParams(layoutParams);
                imageView.setImageBitmap(mybitmap);
                imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
                imageView.setPadding(1, 1, 1, 1);
                imageView.setColorFilter(34);
                imageView.setClickable(true);

                if (mybitmap != null) {
                    layout.addView(imageView);
                   // if (!((BitmapDrawable) imageView.getDrawable()).getBitmap().isRecycled()) {
                   //     ((BitmapDrawable) imageView.getDrawable()).getBitmap().recycle();
                  //  }
                }
                //else {layout.addView(imageView);}
                Log.d("Files", file[i].getName());              
            }
        } catch(Exception e) {Log.d("TAG","Error is " +e);}
    }
}

java android android-imageview

JRowan
  • 6,824
  • 8
  • 40
  • 59
  • I made the modification to the code as you suggested , after setting options.inJustDecodeBounds=true no images were getting loaded into the image view – go sgenq Dec 30 '15 at 01:50
  • I want to click the image and open it in a new activity.. How can i achieve this when the imageview are created at run-time. – go sgenq Dec 30 '15 at 16:34
  • setOnClickListeners to them and pass the path of the picture in the intent to the activity, if you have another question ask it – JRowan Dec 30 '15 at 16:43
  • Sorry.. I do not understand how to create setOnClickListner for run-time imageview. Can you give an example – go sgenq Dec 30 '15 at 16:53
  • Theres a method imageView.setOnClickListener () that you can use inside that you make new View.OnClickListener () and override onclick method and make an intent to switch activity and pass the filepath as an extra to the intent, im not writing an example you can easily research how to do these things and if you get stuck then ask another question on the site – JRowan Dec 30 '15 at 17:07
0

I would suggest to use libraries like Picasso or Glide to handle your bitmaps. They already do all this heavy lifting for you in the most efficient manner possible.

Kshitij Aggarwal
  • 5,287
  • 5
  • 34
  • 41
0

add bitmap.recycle(); try this :

public void LoadImageArray() {
    Bitmap mybitmap;
    LinearLayout layout = (LinearLayout) findViewById(R.id.image_container);
    //LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
    LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(100,100);
    String path= Environment.getExternalStorageDirectory().toString()+"/Pictures";
    File f=new File(path);
    File file[]=f.listFiles();
    BitmapFactory.Options options=new BitmapFactory.Options();
    for (int i = 0; i < 13; i++) {
        layoutParams.setMargins(1, 1, 1, 1);
        layoutParams.gravity = Gravity.LEFT;
        ImageView imageView = new ImageView(this);

        int imageHeight = options.outHeight;
        int imageWidth = options.outWidth;

        String imageType=options.outMimeType;
        if(imageWidth > imageHeight) {
            options.inSampleSize = calculateInSampleSize(options,100,100);//if landscape
        } else{
            options.inSampleSize = calculateInSampleSize(options,100,100);//if portrait
        }
        options.inJustDecodeBounds = false;
        //Bitmap
        try {
            File efile=new File(file[i].getAbsolutePath());
            if(efile.exists()) {
                mybitmap = BitmapFactory.decodeFile(file[i].getAbsolutePath(), options);


                imageView.setLayoutParams(layoutParams);
                imageView.setImageBitmap(mybitmap);
                imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
                imageView.setPadding(1, 1, 1, 1);
                imageView.setColorFilter(34);
                imageView.setClickable(true);

                if (mybitmap != null) {
                    layout.addView(imageView);
                    mybitmap.recycle();// added
                   // if (!((BitmapDrawable) imageView.getDrawable()).getBitmap().isRecycled()) {
                   //     ((BitmapDrawable) imageView.getDrawable()).getBitmap().recycle();
                  //  }
                }
                //else {layout.addView(imageView);}
                Log.d("Files", file[i].getName());              
            }
        } catch(Exception e) {Log.d("TAG","Error is " +e);}
    }
}
S-MILE-S
  • 114
  • 6