开发中给ImageView加载一个高质量图片时,APP抛出了“Canvas: trying to draw too large(840253440bytes) bitmap.”的异常。猜测是图片占用内存太大,超出APP被分配的内存(我用的mate9,APP被分的内存差不多200m),造成了OOM。
解决方法:
1.修改图片分辨率。降低分辨率以减少内存占用,前提是手机展示时不会失真太严重。
2.正确的放置图片资源。把高分辨率的图片放在mipmap-xxhdpi(drawable-xxhdpi)或者mipmap-xxxhdpi(drawable-xxxhdpi).
原因:
1.一张图片占用内存超过200M是很少见的,一张4208x3120的高质量图片才占用50M内存(4208X3120X4),APP内占内存最大的也就只有启动页或引导页,UI设计师一般也是按1280X720来设计,所以引起OOM很大一部分原因是图片资源位置放置不规范引起的。
如:把高质量图片放置在mipmap-ldpi文件夹下。
为什么把高质量图片放置在mipmap-ldpi文件夹下会引起OOM呢?这得从APP加载图片资源的顺序来分析。
1.APP加载图片会根据手机分辨率从相应的文件夹下寻找指定的图片。
比如我的手机是1080X1920,手机像素密度为400dpi,
所以会首先去mipmap-xxhdpi去加载图片资源,如果找不到就去更高级别目录加载(xxxhdpi),如果xxxhdpi目录也没有图片资源,就往下一级目录查找(xhdpi)。
那不按要求放置图片为什么会引起oom呢,这就是要说的重点了。
先上一张图:
图片资源放置的为不正确,上面说了,系统加载图片时,会按照屏幕分辨率去指定的目录加载图片资源,找不到才会去其他目录找,如果在其他目录找到图片资源,系统就会加载该资源,但加载前系统会对图片进行处理(因为不是从相应目录下加载的图片资源,系统加载时会对图片处理以到达需要的分辨率)。
如:我手机分辨率是1080X1920,但是系统没有在xxhdpi目录下加载到需要的图片资源,而是在hdpi文件夹下找到了图片资源,图片可以被正常加载。但是hdpi放的是1.5倍的图,xxhdpi放的是3倍图。1080X1920的手机从hdpi加载的图片就会被系统放大2倍后加载到内存里,比如原图片是28X28,放入mipmap-hdpi的文件夹下,加载到内存中就会变成56X56.