Java Android:内存不足异常/decodeResource如何增加VM预算?

Java Android:内存不足异常/decodeResource如何增加VM预算?,java,android,out-of-memory,Java,Android,Out Of Memory,我是Android新手,一直在开发一款游戏。我时不时会有用户报告内存不足异常,这让我感到惊讶,因为我创建的位图大小最多为200 kb。每当我创建一个新的sprite时,我调用BitmapFactory.decodeResource()。因为我的应用程序是一个僵尸防御游戏,你可以期待我经常创建精灵 每次创建精灵时,我都会调用解码资源来生成位图。我的问题是,如果我只在每个活动开始时调用decode资源,并在包级别引用位图,这会减少VM预算中的内存量吗 当您从图像资源(如png)解码位图时,它 更多

我是Android新手,一直在开发一款游戏。我时不时会有用户报告内存不足异常,这让我感到惊讶,因为我创建的位图大小最多为200 kb。每当我创建一个新的
sprite
时,我调用
BitmapFactory.decodeResource()。因为我的应用程序是一个僵尸防御游戏,你可以期待我经常创建精灵

每次创建精灵时,我都会调用解码资源来生成位图。我的问题是,如果我只在每个活动开始时调用decode资源,并在包级别引用位图,这会减少VM预算中的内存量吗

  • 当您从图像资源(如png)解码位图时,它 更多地取决于图像的尺寸,而不是以KBs为单位的大小
  • 如果您可以在不影响输出的情况下减小原始图像的尺寸,请尝试
  • 尝试重用位图,而不是继续解码它们
  • 使用BitmapFactory.options()对象探索更多选项,例如,增加inSampleSize可以减少图像所需的内存量。 例如
    
    BitmapFactory.Options o=新的BitmapFactory.Options();
    o、 inSampleSize=4;
    o、 inDither=假//禁用抖动模式
    o、 inpurgable=true//告诉gc是否需要空闲内存,位图可以被清除
    myBitMap=BitmapFactory.decodeResource(getResources(),ID,o);
    
  • 如果没有其他优化真正适合您,一个有用的棘手解决方案是,您可以捕获OutOfMemoryException,然后将质量降至最大。。i、 e.将inSampleSize设置为16。它会降低你的图像质量,但至少会使你的应用程序免于崩溃,我在我的一个应用程序中这样做了,我需要在位图中加载巨大的MP图像

我的代码片段从安全资源获取图像。您可以将自己的
sampleSize
设置为图像质量的阈值(越大的
sampleSize
图像质量越低)


来自
inpurgable
的文档:注意:当与
decodeResource(Resources,int,android.graphics.BitmapFactory.Options)
decodeFile(String,android.graphics.BitmapFactory.Options)
一起使用时,此标志将被忽略。 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);
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;
    }
}