.Alpha8:只有一个alpha通道,每个像素占1个字节(Byte)
.Rgb565:只有RGB3个通道,没有alpha通道, R(红)G(绿)B(蓝) 分量分别使用5位、6位、5位,没有透明度,所以一个像素点占 16 位,也就是 2 字节。
.Argb8888:ARGB 分量都是 8 位,ARGB 分量都是 8 位,所以一个像素点占 32 位,也就是 4 字节,它是最能保证图片效果的一种模式
.系统默认格式为:Argb8888
1) Android4.4-Android8.0:图片内存的加载,是在Java 堆栈,android进程的内存占用量为16M,因为bitmap他除了java中持有数据外,底层C++的skia图形库还会持有一个SKBitmap对象,因此一般图片占用内存推荐大小应该不超过8M。如果超过这个限制,会出现OOM异常
2) Android8.0及以上:8.0之后的内存分配是在native,Java层的bitmap创建之后,实际上像素内存的分配是在native层直接调用calloc,所以其像素分配的是在native heap上, 这也是为什么8.0之后的Bitmap消耗内存可以无限增长,直到耗尽系统内存,也不会提示Java OOM的原因,但是会出现native的异常ANR
1) 以一张1080*1920分辨率的图片为例,占用内存=宽*高*像素点大小所占用内存
2) 加载这张图片的原始内存为:1080*1920*4 = 8294400byte = 8100kb =7.91M(约为7.91M)
3) 由于Android图片加载非常耗内测,所以加载图片时,会通过多个途径进行优化:
4) 设置压缩比:为了保证图片正常显示,会根据屏幕/图片/组件大小,设置最优压缩比,设置方式:
val options = BitmapFactory.Options()
options.inSampleSize = 2
val bitmap1 = BitmapFactory.decodeResource(resources, st_xxhdpi, options)
我们以压缩比为2为例:宽和高都为之前的1/2
加载耗用内存为:1080*1/2*1920*1/2*4 = 2073600byte = 2025kb = 1.98M(约为1.98M),为设置压缩比之前的1/4
5) 设置图片色彩模式(默认为Argb8888):
默认是Argb8888是32位,占用4byte(4字节)
在设置压缩比后,将图片色彩模式设置为Rgb565,占用16位,两字节,为默认的1/2,所以设置压缩比并图片色彩模式后,占用内存为1080*1/2*1920*1/2*4*1/2 = 1012.5KB = 0.99M(约为0.99M),为原生的1/8
ldpi: 屏幕密度为120的手机设备
mdpi: 屏幕密度为160的手机设备(此为baseline,其他均以此为基准,在此设备上,1dp = 1px)
hdpi: 屏幕密度为240的手机设备 1.5倍dpi
xhdpi: 屏幕密度为320的手机设备 2倍dpi
xxhdpi:屏幕密度为480的手机设备 3倍dpi
xxxhdpi:屏幕密度为640的手机设备 4倍dpi
同一张1920*1080的图片放在不同资源文件夹下,耗用内存如下(所以对应资源放对应尺寸图 片):
1) 以屏幕宽度为480的手机设备的手机,Imageview为100px * 100px为例:
放在xxhdpi文件夹下,图片尺寸为 100 * 100 * (480 / 480),内存消耗为 1920 *1080 * 480 / 480 * 4 = 8100kb
2) 以屏幕宽度为640的手机设备的手机,Imageview为100px 100px为例: 放在xxxhdpi文件夹下,图片尺寸为 100 * 100 *(480/640)为原始的3/4,内存消耗为 1920 *(480/640)* 1080 (480/640)* 4 = 4556.25kb,为原始的9/16
3) 以屏幕宽度为320的手机设备的手机,Imageview为100px 100px为例:放在xhdpi资源文件下,图片尺寸为100* 100*(480/320)为原始的3/2, 内存消耗为1920*(480/320)*1080*(480/320)*4= 18225kb,为原始的2.25倍
结论为:
图片尺寸为:手机终端的dpi / 图片所在资源目录对应的dpi * 图片尺寸
图片内存为:宽*(手机终端的dpi / 图片所在资源目录对应的dpi)*高*(手机终端的dpi / 图片所在资源目录对应的dpi)*像素点大小所占用内存
网络图片不受文件夹约束,占用内存为:宽*高*像素点大小所占用内存(一般我们通过压缩比和设置色彩模式来调节)网络图片使用Glide框架加载,压缩比已帮我们自动计算,默认色彩模式Argb8888
1) 封装参数:从指定来源,到输出结果,中间可能经历很多流程,所以第一件事就是封装参数,这些参数会贯穿整个过程;
2) 解析路径:图片的来源有多种,格式也不尽相同,需要规范化;
3) 读取缓存:为了减少计算,通常都会做缓存;同样的请求,从缓存中取图片(Bitmap)即可;
4) 查找文件/下载文件:如果是本地的文件,直接解码即可;如果是网络图片,需要先下载;
5) 解码:这一步是整个过程中最复杂的步骤之一,有不少细节;
6) 变换:解码出Bitmap之后,可能还需要做一些变换处理(圆角,滤镜等);
7) 缓存:得到最终bitmap之后,可以缓存起来,以便下次请求时直接取结果;
8) 显示:显示结果,可能需要做些动画(淡入动画,crossFade等)
下载图片是非常耗费资源的,所以图片缓存机制是图片加载框架很重要的一部分:
1.
缓存类型 | 缓存代表 | 说明 |
活动缓存 | ActiveResources | 如果当前对应的图片资源是从内存缓存中获取的,那么会将这个图片存储到活动资源中。 |
内存缓存 | LruResourceCache | 图片解析完成并最近被加载过,则放入内存中 |
磁盘缓存-资源类型 | DiskLruCacheWrapper | 被解码后的图片写入磁盘文件中 |
磁盘缓存-原始数据 | DiskLruCacheWrapper | 网络请求成功后将原始数据在磁盘中缓存 |
2.Glide的缓存机制,主要分为2种缓存,一种是内存缓存,一种是磁盘缓存。
之所以使用内存缓存的原因是:防止应用重复将图片读入到内存,造成内存资源浪费。
之所以使用磁盘缓存的原因是:防止应用重复的从网络或者其他地方下载和读取数据。
正式因为有着这两种缓存的结合,才构成了Glide极佳的缓存效果。
3.Glide详解链接:
本文发布于:2024-01-31 19:45:52,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170670155530930.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |