Android: Out of Memory Exception / How does decode

2020-07-13 07:23发布

I am pretty new to Android and have been developing a game. Every now and again I have users reporting out of memory exceptions, which I find surprising since the bitmaps that I create are at most 200 kb in size. I call BitmapFactory.decodeResource() whenever I create a new sprite. Since my application is a zombie defense game, you could expect that I create sprites quite often.

Every time I create a sprite, I call decode resource to generate a bitmap. My question is if I was to only call decode resource at the start of each activitiy, and refer to the bitmap at package level, would this lessen the amount of memory placed on the VM Budget?

2条回答
倾城 Initia
2楼-- · 2020-07-13 08:13

My snippet to get image from resources safety. You can set your own sampleSize as threshold of image quality (larger sampleSize is lower image quality).

public static Bitmap loadBitmapSafety(int resDrId,  Context context){
    return loadBitmapSafety(resDrId, 1, context);
}

private static Bitmap loadBitmapSafety(int resDrId, int sampleSize, Context context){
    BitmapFactory.Options ops = new BitmapFactory.Options();
    ops.inSampleSize = sampleSize;

    try {
        return BitmapFactory.decodeResource(context.getResources(), resDrId, ops);

    } catch (OutOfMemoryError e) {
        if (sampleSize == 4)
            return null;
        return loadBitmapSafety(resDrId, sampleSize +1, context);

    } catch (Exception e){
        return null;
    }
}
查看更多
欢心
3楼-- · 2020-07-13 08:16
  • When you decode the Bitmap from an image resource like png, it depends more on the dimensions of image rather then the size in KBs.
  • Try if you can reduce the dimensions of original image without really impacting your output.
  • Try reusing the bitmaps rather then keep decoding them.
  • Explore more options with BitmapFactory.Options() object, for example increasing inSampleSize can reduce the amount of memory required by the image. e.g
    BitmapFactory.Options o=new BitmapFactory.Options();
    o.inSampleSize = 4;
    o.inDither=false;                     //Disable Dithering mode
    o.inPurgeable=true;                   //Tell to gc that whether it needs free memory, the Bitmap can be cleared
    myBitMap=BitmapFactory.decodeResource(getResources(),ID, o);
    
  • One useful tricky solution if no other optimizations are really working out for you is that, you can catch the OutOfMemoryException and then can reduce the quality to max.. i.e. setting the inSampleSize to 16. It will reduce the quality of your images but at least will save your application from crashing, i did this in one of my app where I needed to load huge MP image in a bitmap.
查看更多
登录 后发表回答