美文网首页AndroidAndroid进阶之路Android 开发技术分享
Android 图片资源的目录 -- 一个背景图片引发的内存 O

Android 图片资源的目录 -- 一个背景图片引发的内存 O

作者: 赤兔欢 | 来源:发表于2017-10-07 17:55 被阅读149次

在开发中应用突然crash, 从日志上看是解压图片内存不足导致发生了OOM。

Caused by: java.lang.OutOfMemoryError: Failed to allocate a 85881612 byte allocation with 16777216 free bytes and 69MB until OOM

用Android monitor 看了下内存,打开这个Activity时,内存直接跳涨了60M左右。好崩溃。

oom_oom.png

看了下这个Activity有一个背景,背景为png图片。注释掉这个背景图片后,从Android Monitor 上看内存的曲线平滑了。原因就是这张图片了。但是一张图片也不能吃掉60M的内存。

res/mipmap/pc_car.png: PNG image data, 1440 x 1217, 8-bit/color RGBA, non-interlaced

分辨率大小为 1440x1217, 32为像素,解压后大小应该为6M, 还是不能解释上面的原因。

用Android Motinor 把内存dump 出来。

oom_monitor_bitmap.png

这张bitmap 大小为85881640,大约为81M。然后看下分辨率

weixin.png

微信的背景图只放在了drawable 和drawable-hdpi 目录。 在hdpi 目录单独放可能是为了在低端机上适配,节约内存。 以ba.jpg 为例, 320x480 大小,解压后为600K, 在XXXHDPI 手机上放大后为5.4M。

MBC02T6468G8WN:res louie.wang$ find . -name b*.jpg
./drawable/ba.jpg
./drawable/bb.jpg
./drawable/bd.jpg
./drawable/be.jpg
./drawable-hdpi-v4/bb.jpg
./drawable-hdpi-v4/bd.jpg
./drawable-hdpi-v4/be.jpg

./drawable/ba.jpg: JPEG image data, baseline, precision 8, 320x480, frames 3

鹅厂的QQ:

QQ.png

QQ 应该使用了插件开发,目录比较简单。手机QQ 在drawable 目录下放了很多背景图,图片都不是太大,但是在高分辨率手机上肯定有内存的占用问题。而且QQ没有提供 XXXHDPI 的资源。

手淘:

taobao.png

手淘也采用了插件开发,整个目录清爽了很多。和QQ一样,手淘在drawable 目录放了很多背景图片。没有根据不同的分辨率单独出图。 值得注意的是手淘有一个 drawable-anydpi-v21 目录

ls drawable-anydpi-v21/
design_ic_visibility_off.xml

MBC02T6468G8WN:res louie.wang$ find . -name design_ic_visibility_off.*
./drawable-anydpi-v21/design_ic_visibility_off.xml
./drawable-mdpi-v4/design_ic_visibility_off.png
./drawable-xhdpi-v4/design_ic_visibility_off.png
./drawable-xxhdpi-v4/design_ic_visibility_off.png
./drawable-xxxhdpi-v4/design_ic_visibility_off.png

手机百度:

baidu.png

手机百度 的drawable 目录也放了20 张左右的背景图片。但是手机百度有一个 drawable-nodpi
目录。

ls drawable-nodpi-v4/
back_btn.png   bt_white.9.png    city_search_bg.9.png       titlebar_bg.9.png
bt_grey.9.png  bt_white_p.9.png  groupon_titlebar_bg.9.png  union_list_bg_middle.9.png

根据Google 的指引,

screens_support
nodpi 适用于所有密度的资源。这些是密度独立的资源。不管当前屏幕的密度如何,系统都不会 缩放以此限定符标记的资源。

SVG 图片

在手机淘宝的res 目录下有一个 drawable-anydpi-v21 目录,用来放在矢量图片的。

Google 关于svg 和anydpi的解释:

anydpi:此限定符适合所有屏幕密度,其优先级高于其他限定符。 这对于矢量可绘制对象很有用。 此项为 API 级别 21 中新增配置

Android 4.4(API 级别 20)及更低版本不支持矢量图。如果最低 API 级别设置为上述 API 级别之一,则在使用 Vector Asset Studio 时您有两个选择:生成便携式网络图形 (PNG) 文件(默认)或使用支持库。为实现向后兼容性,Vector Asset Studio 会生成矢量图的光栅图像。矢量和光栅图一起打包到 APK 中。您可以在 Java 代码中以 Drawable 的形式引用矢量图,或在 XML 代码中以 @drawable 的形式引用矢量图;当您的应用运行时,对应的矢量或光栅图像会自动显示,具体取决于 API 级别。

在淘宝的的drawable-anydpi 放了一张design_ic_visibility_off.xml 图片,在drawable-* 目录下都有对应的png 图片。这是Android Studio 自动生成的。

进入自己的工程中找一张SVG 图片看下,可以看到把SVG图片放在了drawable 目录,然后AS 自动的从drawable 目录中把SVG图片分离出来,放在了 drawable-anydpi-v21 目录,同时在对应的drawable-**hdpi 目录下生成png 图片。

MBC02T6468G8WN:AndroidSample louie.wang$ find . -name ic_user.*
./app/build/generated/res/pngs/debug/drawable-anydpi-v21/ic_user.xml
./app/build/generated/res/pngs/debug/drawable-hdpi/ic_user.png
./app/build/generated/res/pngs/debug/drawable-ldpi/ic_user.png
./app/build/generated/res/pngs/debug/drawable-mdpi/ic_user.png
./app/build/generated/res/pngs/debug/drawable-xhdpi/ic_user.png
./app/build/generated/res/pngs/debug/drawable-xxhdpi/ic_user.png
./app/build/generated/res/pngs/debug/drawable-xxxhdpi/ic_user.png
./app/build/intermediates/res/merged/debug/drawable-anydpi-v21/ic_user.xml
./app/build/intermediates/res/merged/debug/drawable-hdpi/ic_user.png
./app/build/intermediates/res/merged/debug/drawable-ldpi/ic_user.png
./app/build/intermediates/res/merged/debug/drawable-mdpi/ic_user.png
./app/build/intermediates/res/merged/debug/drawable-xhdpi/ic_user.png
./app/build/intermediates/res/merged/debug/drawable-xxhdpi/ic_user.png
./app/build/intermediates/res/merged/debug/drawable-xxxhdpi/ic_user.png
./app/src/main/res/drawable/ic_user.xml

同样把图片放到 drawable-anydpi 目录

MBC02T6468G8WN:AndroidSample louie.wang$ find . -name ic_user.*
./app/build/generated/res/pngs/debug/drawable-anydpi-v21/ic_user.xml
./app/build/generated/res/pngs/debug/drawable-hdpi/ic_user.png
./app/build/generated/res/pngs/debug/drawable-ldpi/ic_user.png
./app/build/generated/res/pngs/debug/drawable-mdpi/ic_user.png
./app/build/generated/res/pngs/debug/drawable-xhdpi/ic_user.png
./app/build/generated/res/pngs/debug/drawable-xxhdpi/ic_user.png
./app/build/generated/res/pngs/debug/drawable-xxxhdpi/ic_user.png
./app/build/intermediates/res/merged/debug/drawable-anydpi-v21/ic_user.xml
./app/build/intermediates/res/merged/debug/drawable-hdpi/ic_user.png
./app/build/intermediates/res/merged/debug/drawable-ldpi/ic_user.png
./app/build/intermediates/res/merged/debug/drawable-mdpi/ic_user.png
./app/build/intermediates/res/merged/debug/drawable-xhdpi/ic_user.png
./app/build/intermediates/res/merged/debug/drawable-xxhdpi/ic_user.png
./app/build/intermediates/res/merged/debug/drawable-xxxhdpi/ic_user.png
./app/src/main/res/drawable-anydpi/ic_user.xml

可以得出如下结论:

  1. App icon 放在mipmap-XXX 目录。放在drawable-XXX 目录也可以,只是某些情况下图片没那么清晰。
  2. 背景图片资源 放在 drawable-nodpi 目录。这样避免自动放大图片。
  3. 自定义的 drawable XML 放在 drawable 目录
  4. SVG 文件可以放在drawable-anydpi 目录,根据Google Doc, anydpi 后缀是特备为矢量图准备的。

相关文章

网友评论

  • Bo动:你好,请问如果1080*1920像素的图片放在nodpi下作为某个页面整体背景,在低于1080*1920分辨率的机型上是不是看不全图片?或者说在高于这个分辨率上的机型上则是填充不满的情况?
    赤兔欢:不会,draw 的是后自动填充 @云波丽

本文标题:Android 图片资源的目录 -- 一个背景图片引发的内存 O

本文链接:https://www.haomeiwen.com/subject/xwajyxtx.html