type
status
date
slug
summary
tags
category
icon
Bitmap 是内存优化逃不了的一个东西,本文探讨下,Bitmap 中的 density 到底是什么东西,它是如何影响到内存的使用的
先看下 density 的文档注释
简单来说 density 是用来绘制缩放用的,默认情况下的 density 就是屏幕的 density(
resources.displayMetrics.densityDpi
),假如我修改了一张 Bitmap 的 density,那么图片的显示应该会发生缩放,写个简单的 demo 验证下<!-- more -->
界面
输出:
从输出可以看出,Bitmap 的 density 只是会影响到显示而已,并不会影响到 Bitmap 本身的大小,所以这个属性不会影响到内存占用过多的问题
界面中可以看出,density 导致图像的缩小一倍和放大一倍
那么影响内存的是什么呢,我们知道把一张 xxhdpi 的图片放到 xhdpi 中是不行的,这样会导致图片扩大,这里的扩大是指图片本身内存占用的扩大,而不是显示上面的,跟踪下
BitmapFactory.decodeResource(resources, R.drawable.male_xhdpi)
的代码调用,跟踪到 decodeResourceStream()
函数的时候,发现了 density 的身影发现 Options 里面有两个属性 (
inDensity
,inTargetDensity
),inTargetDensity
被赋值成了当前设备的像素密度,那么 inDensity
被赋值成啥了呢?代码中看是赋值成了参数 value 的 density,回溯函数看看 value.density 是哪里来的TypeValue 的值只有在这里有写入现象,猜测是根据 resource 的等级来赋值的,比如 xhdpi 就是 320dpi,xxhdpi 就是 480dpi(这些数值可以在官网查看),写段代码测试下
输出
恩,看来这个推测很准确
既然知道了这两个数值是什么意义,那么继续跟踪代码,跟踪后发现最后调用的是一个 native 函数
去 androidXRef 看下这部分的代码
忽略了多余的代码,分析部分看中文注释
可以在代码中看到,Options 的
inDensity
和 inTargetDensity
是用作 Bitmap 的缩放用的,此缩放并不是视觉上的缩放,而是缩放了 Bitmap 的真正尺寸,那么这里就需要注意内存上的消耗了,不要把 xxhdpi 的图片放到 xhdpi 下面对于上面的 inScreenDensity,在 decodeResource 的流程里面并没有发现它的赋值过程,那么它肯定是初始值 0,查看了下注释,他表示当前 display 设备的 density,如果 inScreenDensity == density 就不会对图片进行缩放
总结下过程:
通过 resource 获取 Bitmap 的时候,先根据资源文件获得
inDensity
,inTargetDensity
就是当前设备的 density,图片解码后在通过 canvas 缩放 inTargetDensity / inDensity
个倍数,就获得了缩放尺寸后的 Bitmap- Author:NotionNext
- URL:https://tangly1024.com/article/37e622b3-ca18-4ab5-bf6e-6bf273d2ea8f
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!
Relate Posts