解决android 大图OOM的两种方法

时间:2023-01-07 19:41:50

最近做程序中,需要用到一张大图。这张图片是2880*2180大小的,在我开发所用的华为3C手机上显示没有问题,但是给米3装的时候,一打开马上报OOM错误。给nexus5装,则是图片无法出来,DDMS中打印堆溢出异常。于是开始看这个问题。

到stackvoerflow.com上找答案,发现一种很简单又巧妙的解决方法,就是新建一个drawable-nodpi的文件夹,然后把图片放在里面。对于其中的原因是,Android对于不同屏幕大小的手机,由于会去自动缩放图片以适应屏幕,所以会占用2倍的内存大小。而放在nodpi中,是为了让android系统不去缩放它。

另外一种方法就是设置options.inPreferredConfig了,共有4种配置,分别是RGB_565, ALPHA_8, ARGB_4444, ARGB_8888。代码如下:

        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inPreferredConfig = Bitmap.Config.RGB_565;
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.road, options);

对于这4种配置,我在把图片放在hdpi和放在nodpi分别测试了它们的占用内存情况,数据如下:

把图片放在drawable-hdpi中,分别占用的内存:

05-20 15:07:19.197  32625-32625/cn.irains.parkinglay_by.app D/ParkingBitmapFragment﹕ RGB_565:22118400
05-20 15:07:19.916  32625-32625/cn.irains.parkinglay_by.app D/ParkingBitmapFragment﹕ ALPHA_8:44236800
05-20 15:07:20.976  32625-32625/cn.irains.parkinglay_by.app D/ParkingBitmapFragment﹕ ARGB_4444:22118400
05-20 15:07:21.444  32625-32625/cn.irains.parkinglay_by.app D/ParkingBitmapFragment﹕ ARGB_8888:44236800

把图片放在drawable-nodpi中,分别占用的内存:

05-20 15:14:32.741      736-736/cn.irains.parkinglay_by.app D/ParkingBitmapFragment﹕ RGB_565:12441600
05-20 15:14:32.853      736-736/cn.irains.parkinglay_by.app D/ParkingBitmapFragment﹕ ALPHA_8:6220800
05-20 15:14:33.036      736-736/cn.irains.parkinglay_by.app D/ParkingBitmapFragment﹕ ARGB_4444:12441600
05-20 15:14:33.181      736-736/cn.irains.parkinglay_by.app D/ParkingBitmapFragment﹕ ARGB_8888:24883200

可以看到,在放在drawable-hdpi的情况下,ALPHA_8和ARGB_8888占用的是同样大小的内存,约42M。而用ARGB_4444和RGB_565则省下了一半的内存,约21MB。

而如果放在drawable-nodpi中,ARGB_8888少了近一半的内存,占用内存不到24M,RGB_565和ARGB_4444是一样的,共占用不到12MB,是使用ARGB_8888时的一半。ALPHA_8占用更少,不到6M。

另外,对于OOM问题,如果你的图片大小大过你所需要的大小的话,还可以进行缩放再显示。相关方法网上搜索Android OOM,能找到许多答案,这里不再赘述。