android-Bitmap那些事儿

2017-02-06  本文已影响69人  好奇的小刺猬

整理了几篇文章总结:

缓存有啥作用:

Bitmap到底占用了多少内存

BitmapFactory中的以下几个变量的注释中解释了各自的作用,大概说来就是他们和inScaled变量一起确定了返回的bitmap的缩放情况,也就是影响实际读取到内存中的大小。

inTargetDensity:application实际运行时获取到的设备的dpi信息。是影响bitmap读取时scale的关键。

inScreenDensity:设备的dpi,也就是显示屏幕的dpi。

inDensity:一个跟drawable所属dpi有关的值,如果没有相应的dpi归类,则被设置为默认值DENSITY_MEDIUM也就是160。
参考一段BitmapFactory中的代码:

    /**
     * Decode a new Bitmap from an InputStream. This InputStream was obtained from
     * resources, which we pass to be able to scale the bitmap accordingly.
     */
    public static Bitmap decodeResourceStream(Resources res, TypedValue value,
            InputStream is, Rect pad, Options opts) {

        if (opts == null) {
            opts = new Options();
        }

        if (opts.inDensity == 0 && value != null) {
            final int density = value.density;
            if (density == TypedValue.DENSITY_DEFAULT) {
                opts.inDensity = DisplayMetrics.DENSITY_DEFAULT;
            } else if (density != TypedValue.DENSITY_NONE) {
                opts.inDensity = density;
            }
        }
        
        if (opts.inTargetDensity == 0 && res != null) {
            opts.inTargetDensity = res.getDisplayMetrics().densityDpi;
        }
        
        return decodeStream(is, pad, opts);
    }

对于读取文件生成的bitmap到底占用了你多少资源,这篇blog[1]

从源代码的角度说的比较清楚了。不过除此之外,我的理解,如果放到了assets或者直接读取文件,也就是不从drawable中取得的话,需要看decode的时候怎么设置的BitmapFactory.Options,如果opt是null,inDensity应该是默认值mediumDpi也就是160。BitmapFactory和Bitmap类里对这一部分比较清楚,关键点还是去看源代码比较好。

小结:影响Bitmap占用内存的几个点:

  1. 色彩格式:ARGB8888,RGB565
  2. 原始文件存放的资源目录:hdpi,xhdpi等,从相应资源文件夹下读取到的图片资源会将这个dpi信息传递给opts.inTargetDensity
  3. 目标屏幕的密度。

减少Bitmap的内存占用,防止OOM

使用内存、文件、网络缓存的策略减少重复加载,基础的缓存方式是LRU算法。当然也可以根据业务需求使用合适的缓存或者加载策略,如有有个场景频繁读入bitmap并不确定性相互切换,但是并不是每张都重复使用,比如目前比较火的类似FaceU的动态贴纸选择。此时就不能直接将这些图片全都缓存,否则会由于命中率低造成巨大的内存浪费。
关于内存分析的方法,可以参考这篇Android最佳性能实践(二)——分析内存的使用情况[4]


  1. Android 开发绕不过的坑:你的 Bitmap 究竟占多大内存?

  2. 解析Android开发优化之:对Bitmap的内存优化详解

  3. 【MDCC 2015】开源选型之Android三大图片缓存原理、特性对比

  4. Android最佳性能实践(二)——分析内存的使用情况

上一篇 下一篇

猜你喜欢

热点阅读