0

I know this must be one of the most asked things at SO, but none of the other answers gave me a solution. But from reading the other answers, looks like I'll need to redesign the way the App is working.

It's like this, we have a ScrollView, which will inflate some views. A ListView can't be used in this situation, because to behave the way we want it would require extending the ListView, and this is something we don't want to do (even though this seems to be our only solution to our current way of showing items, because of this OOM exception). The list can have a lot of columns per row, and the bigger the screen, more columns it will have.

Each inflated View has a layout displaying some info from the database, including a picture. This picture is stored through a byte array. It's any picture taken with the device camera. Currently every photo (byte array) is taking 800kb to 1mb, which seems a lot to me. Now the list have 30+ items. I took photos until the OOM happened, and it happened when I took a total of 6 photos (occasionally 7). That would be 8mb-9mb of data. Everytime I go to other Activity, and go back to the Activity the ScrollView is in, the list needs to be repopulated.

This is the snippet of the PopulateList method:

if (item.getImg() != null) {

            if (App.debug) {

                Log.d(TAG, "Setting bmp.");
            }

            Bitmap bmp = App.byteArrayToBmp(item.getImg());

            imgV.setImageBitmap(bmp);
        }

Every inflated View will open an 'Advanced Dialog', which will contain other info. Maybe the Image could be there instead on the list (meaning that there would be only 1 bitmap, as every inflated View shares the same advanced dialog). Or I could extend the ListView and benefit from it recycling method (It's not a good solution as I though it would be considering more than 6 items can be at the screen). Another thing that bothers me is every picture having 800kb. Seems like a lot for a 128x128.

This is the setup for the size:

cameraParams.setPictureSize(App.pxToDpi(128), App.pxToDpi(128));
cameraParams.setPictureFormat(PixelFormat.JPEG);

camera.setParameters(cameraParams);

public static int pxToDpi(int px) {

    final int scale = app.getApplicationContext().getResources().getDisplayMetrics().densityDpi;

    int pixels = (int) px * (scale / 160);

    return pixels;
}

So, do you think there is a solution to my issue keeping the current model of my App, or will I need to reformulate?

EDIT: The bitmap method:

public static Bitmap byteArrayToBmp(byte[] byteArray) {

    Bitmap img = null;

    BitmapFactory.Options opts = new BitmapFactory.Options();

    opts.inSampleSize = 2;

    img = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length, opts);

    return img;
}
2
  • Show us the code of how you create your bitmap. You could decode it at a lower res. If its just a thumb Commented Jun 14, 2012 at 21:10
  • @Blundell take a look at the edit. Commented Jun 14, 2012 at 21:11

1 Answer 1

2

You might want to look at the Official Android Training docs, they've just been updated:

Check out Displaying Bitmaps Efficiently with the lesson: Loading Large Bitmaps Efficiently that goes over this.

Basically you can decode the image using sampleSize to decode it to the width and height you want:

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) {
        if (width > height) {
            inSampleSize = Math.round((float)height / (float)reqHeight);
        } else {
            inSampleSize = Math.round((float)width / (float)reqWidth);
        }
    }
    return inSampleSize;
}

Explained in much great detail in the links above

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

1 Comment

Very interesting. I'll read this and see if I can solve this problem. But I really wonder if this will have any effect, since I'm already setting the picture at 128x128 in the line: cameraParams.setPictureSize(App.pxToDpi(128), App.pxToDpi(128)); Will give it a shot, though.

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.