我正在研究的项目使用了几个“高分辨率”背景(请注意引号)。只是为了进入情境,其中一个是640x935 1.19M PNG文件。据我所知,即使Android将图像作为原始数据解压缩到内存中,也应该是:
640 x 935 x 4bytes = 2.39M
我的项目存在内存问题,我无法理解,我希望有人可以对这个问题有所了解。我将列出我正在开发的两个设备以及一些结果。
为了确保这不是次要问题,我在第一次创建活动时没有加载背景,然后当用户按下按钮时,它所做的只是:
findViewById(R.id.completed_block_background).setBackgroundResource(R.drawable.blockbackgroundbottom1);
然后,在进程上使用带有“Update Heap”的DDMS(并且首先强制GC确保这不会有问题),我得到以下内存结果:
Nexus S:从18M变为26M(8M差异)
Galaxy Nexus:从28M变为39M(差异为11M)
因此,正如您所看到的,将理论上2.39M未压缩的图像放入背景实际上会增加8M和11M的内存使用量。有人可以解释为什么会这样,有没有解决方案?
我能找到的唯一解决方案是使用位图将分辨率降低一半或降低通道格式(到目前为止,这是我所做的,将它们切换到565 RGB,但这会产生一些我无法接受的条带问题)。
如果没有什么可以做的话,我也会接受,解释为什么会这样。提前谢谢。
答案 0 :(得分:111)
这就是为什么它让图像如此之大?
嗯,正在发生的事情是setBackgroundResource(R.drawable.blockbackgroundbottom1)
会导致Android首先执行您尝试过的BitmapFactory.decodeResource()
事物,但随后让渲染逻辑缩放图像以将其应用为背景。因此,例如,Galaxy Nexus和Nexus S之间的3MB差异可能反映了LinearLayout
的再现之间的大小差异(以像素为单位)。
根据屏幕密度,可能还会进行一些重新取样,具体取决于您在资源树中存储此图像的位置。
有没有办法让它以任何方式保持原始图像尺寸?
关闭袖带,我会先尝试将其放入res/drawable-nodpi/
(以防止任何基于密度的自动重新取样),然后通过Bitmap
的版本手动获取BitmapFactory.decodeResource()
BitmapFactory.Options
,因此您可以在阅读时对其进行缩放。如果这似乎没有多大帮助,您可能需要将PNG从可绘制资源中转移到原始资源或资源中,如Android可能仍会尝试保留图像的未缩放副本。我不认为如果你自己直接使用BitmapFactory.decodeResource()
,我就不能排除它。