0

I'm trying to have live tile images in my application. I tested the functionality on some devices (API>22) and they work. But now i'm testing on API 22 and i'm getting the error in the title. I've searched through the site and I found this to be particularly helpful OutOfMemoryExceptionGridView. But I'm loading my images (straight from the res folder) to an array, then using a viewflipper to make the slideshow

How do I change my block of code (to fix the main OOME) since what I linked above uses bitmaps, and I am directly calling the res id.

This is my code:

@Override
    public View onCreateView(LayoutInflater inflater, final ViewGroup container,
                             Bundle savedInstanceState) {

       int[] images = {R.drawable.img1, R.drawable.img2, R.drawable.img3}; //store images into array
        viewFlipper = view.findViewById(R.id.firstTile); //main tile to have slideshow
         for (int image : images) {
            flipperImages(image); //performs the slideshow per image
        }
}
 public void flipperImages(int image) {
        ImageView imageViewFirstTile = new ImageView(getContext());
        imageViewFirstTile.setBackgroundResource(image);
        viewFlipper.addView(imageViewFirstTile);
        viewFlipper.setFlipInterval(12500);
        viewFlipper.setAutoStart(true);
        viewFlipper.setInAnimation(getContext(), android.R.anim.slide_in_left);
        viewFlipper.setOutAnimation(getContext(), android.R.anim.slide_out_right);
    }

How can I fix the main error with this implementation (calling the res id of the images directly)?

1 Answer 1

0

If the images can be scaled down to avoid loading the full sized images, I would consider that as a first step. There is no need to load the full-sized Bitmaps into memory if they window in which they're displayed is a fraction of the size. In your current approach, the images are not subsampled and as a result the entire Bitmap is loaded into memory at it's full size. So you have 3 full sized Bitmaps in memory.

For subsampling an image, see the following code. (Source: https://developer.android.com/topic/performance/graphics/load-bitmap)

/* reqWidth and reqHeight would be the dimensions of your ImageView or some other preferred dimensions. For example, if your Bitmap is 500 X 500 and your ViewFlipper/ImageView is only 100 X 100, passing 100 as reqWidth and 100 as reqHeight will subsample the image until it's dimensions are close to the 100 X 100. This will largely shrink the size loaded into memory. */ 
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);
}


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

Sign up to request clarification or add additional context in comments.

2 Comments

This works perfectly. I'm a little confused though. What do I change to increase the sizes of the image? Right now they are too small. I've changed imageViewFirstTile.setImageBitmap(decodeSampledBitmapFromResource(getResources(),image,300,100)); but I see no visible changes and my pictures aren't filling the image view
They should probably be the size of your ViewFlipper. Or in your ImageView I believe you can setScale to XY which would stretch them to the entire dimensions of your ImageView.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.