4

I am getting OutOfMemoryError while I am adding variable background to gridview... at

final Bitmap shelfBackground = BitmapFactory.decodeResource(resources, background);

Here is my code.

public class ShelvesView extends GridView {
    private Bitmap mShelfBackground;
    private int mShelfWidth;
    private int mShelfHeight;
    public ShelvesView(Context context) {
        super(context);
    }
    public ShelvesView(Context context, AttributeSet attrs) {
        super(context, attrs);
        load(context, attrs, 0);
    }
    public ShelvesView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        load(context, attrs, defStyle);
    }

    private void load(Context context, AttributeSet attrs, int defStyle) {
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ShelvesView,   defStyle, 0);
        int imageWidth = options.outWidth;
        final Resources resources = getResources();
        final int background = a.getResourceId(R.styleable.ShelvesView_shelfBackground, 0);
        final Bitmap shelfBackground = BitmapFactory.decodeResource(resources, background);
        if (shelfBackground != null) {
            mShelfWidth = shelfBackground.getWidth();
            mShelfHeight = shelfBackground.getHeight();
            mShelfBackground = shelfBackground;
        }

        a.recycle();
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        final int count = getChildCount();
        final int top = count > 0 ? getChildAt(0).getTop() : 0;
        final int shelfWidth = mShelfWidth;
        final int shelfHeight = mShelfHeight;
        final int width = getWidth();
        final int height = getHeight();
        int bottom = (count > 0) ? getChildAt(count - 5).getBottom() + shelfHeight : 0;
        final Bitmap background = mShelfBackground;
        for (int x = 0; x < width; x += shelfWidth) {
            for (int y = top; y < height; y += shelfHeight) {
                canvas.drawBitmap(background, x, y, null);
            }
        }

        //drawDecorations(canvas, top, shelfHeight, width);

        // canvas.drawBitmap(mShelfLeftLayer,0,bottom, null);

        super.dispatchDraw(canvas);
    }

}
Arount
  • 9,853
  • 1
  • 30
  • 43
indraja machani
  • 679
  • 1
  • 9
  • 25

3 Answers3

4

Add Bitmap Option to it -

BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 8;
shelfBackground = BitmapFactory.decodeResource(resources, background, options);
Pie
  • 262
  • 2
  • 10
  • I have tried that one .but then I am getting error at "canvas.drawBitmap(background, x, y, null);" – indraja machani Sep 26 '12 at 07:41
  • I am getting the following error log.. and (ShelvesView.java:72) is "canvas.drawBitmap(background, x, y, null);" in dispatchDraw method E/AndroidRuntime( 6296): java.lang.NullPointerException E/AndroidRuntime( 6296): at android.view.GLES20Canvas.drawBitmap(GLES20Canvas.java:692) E/AndroidRuntime( 6296): at android.view.GLES20RecordingCanvas.drawBitmap(GLES20RecordingCanvas.java:103) E/AndroidRuntime( 6296): at com.example.home.ShelvesView.dispatchDraw(ShelvesView.java:72) – indraja machani Sep 26 '12 at 09:50
2

Use the example from Android SDK for processing images off the UI Thread :

class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
private final WeakReference<ImageView> imageViewReference;
private int data = 0;

public BitmapWorkerTask(ImageView imageView) {
    // Use a WeakReference to ensure the ImageView can be garbage collected
    imageViewReference = new WeakReference<ImageView>(imageView);
}

// Decode image in background.
@Override
protected Bitmap doInBackground(Integer... params) {
    data = params[0];
    return decodeSampledBitmapFromResource(getResources(), data, 100, 100));
}

// Once complete, see if ImageView is still around and set bitmap.
@Override
protected void onPostExecute(Bitmap bitmap) {
    if (imageViewReference != null && bitmap != null) {
        final ImageView imageView = imageViewReference.get();
        if (imageView != null) {
            imageView.setImageBitmap(bitmap);
        }
    }
}

}

Here you can find more examples for decoding with sampleSize decodeResource.

hardartcore
  • 16,886
  • 12
  • 75
  • 101
1

You can use BitmapFactory.Options class to crop image to any size.

You can use following:

BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
options.inSampleSize = 8; // 1/8th of actual image.
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;

For more info, please see this.

Here, when you use a Bitmap, always call its bmp.recycle() method, since GC can't clear the memory held by Bitmap, if your bitmap is not getting garbage collected, then also you get the OME.

Also I have given generic solution, please see this.

Community
  • 1
  • 1
Shrikant Ballal
  • 7,067
  • 7
  • 41
  • 61