为什么我的 160kb 应用程序背景在 运行 时间变成了 49MB?

Why does my 160kb app background become 49 MB at run time?

我决定调查我的应用程序的内存使用情况,我查看了 Android Studio 的内存监视器,发现我的内存使用量约为 68 MB。我觉得太高了。

我打开了内存分配器,从应用程序的开头开始跟踪。我看到有一个 NonMovableArray 的 49 MB 分配,这是一个 Bitmap

我调试了应用,发现是我用的后台。下面的行来自 PhoneWindow.java 文件,我相信这是 Android 将背景分配给屏幕的地方。背景对象的大小为 49 MB,分辨率为 2625x4669。

我的应用程序没有透支,而且我有一个应用到整个主题的背景。

我在 drawable 文件夹中有一个 JPG 格式的可绘制背景,分辨率为 750x1,334。

PhoneWindow.java

if (mBackgroundResource != 0) {
    background = getContext().getDrawable(mBackgroundResource);
} else {
    background = mBackgroundDrawable;
}

我正在摩托罗拉 Nexus 6 设备上进行测试,该设备密度为 560,分辨率为 1440 x 2560。

有两点不明白

  1. 如果设备的分辨率为 1440x2560,为什么我的背景会转换为 2625x4669?
  2. 即使这种转换是应用程序的最佳方案,为什么 160 KB 的文件最终会变成 49 MB?

如果你们能向我解释一下,那就太好了。谢谢!

我不确定分辨率差异,但所用内存和文件大小之间的差异是因为 JPG 格式的图像(与许多其他格式一样格式)被压缩(参见 wiki 了解如何)。当您随后将其加载到内存中时,它不再被压缩,因为它用于绘制屏幕上的每个像素。

If the device has a resolution of 1440x2560, why would my background get converted to 2625x4669?

您将图像放入 res/drawable/。这不是一个好的选择,因为它是 res/drawable-mdpi/ 的同义词。因此,Android 正在对您的图像重新采样,认为您的目标是 -mdpi 设备(~160dpi),因此图像在 Nexus 6 上的物理尺寸大致相同(密度的 3.5 倍)。

res/drawable-nodpi/res/drawable-anydpi/ 是正确的选择在一定程度上取决于您对该资源的替代版本,尽管 either will probably work.

how come a 160 KB file would end up being 49 MB?

图像占用 160KB 磁盘。内存占用是解码后的图像。对于 ARGB_8888 图像,这将是图像分辨率(post-重采样)乘以 4 bytes/pixel。 2625x4669x4 ~= 49MB.

Bitmap 的默认和最高质量配置是 ARGB_8888,每个像素将使用 4 个字节。由于您的图像被缩放到 2625*4669,因此:

2625*4669*4 bytes = 49024500 bytes

http://developer.android.com/reference/android/graphics/Bitmap.Config.html