关于图片优化,大概如下
为什么要进行图片优化
相信大概刚开始学习 Android 的时候有过图片过大而直接报错的情况,下面简单介绍一下 OOM 问题,Android 支持的图片格式及图片优化的几种方式
什么是 OOM?:Android 系统的进程(APP 级别)有最大的内存限制,超过这个限制系统就会抛出)OOM 错误
图片 OOM 问题产生的几种情况
- 一个页面一次加载过多的图片
- 加载大图片没有进行压缩
3.Android 列表加载大量 bitmap 没有使用缓存(第三方框架)
Android 支持的图片格式
png:无损压缩的图片格式,支持透明通道,占用的空间一般比较大
Jpeg:有损压缩的图片格式,不支持透明通道
webp:由谷歌 2010 年发布,支持无损与有损,比较理想
gif:支持多帧动画,但安卓本身图片库不支持,需要用到第三方框架
为了方便理解,还得介绍一下图片占用内存的知识
如何计算:图片宽_图片高_一个像素占的内存大小
所以由上可见,图片储存优化的方式如下
- 尺寸优化:通过减小宽高来实现
- 质量压缩:改变一个像素占用的内存(优化解码率)
- 内存重用:需要用到 inBitmap 属性
尺寸压缩
主要起作用的为两个方法
intJustDecodeBounds=true(可以在不加载图片的情况下获得图片的宽高)
inSampleSize(用合适的压缩比)
!!!如果只是单纯的改变 ImageView 的大小,不会对图片产生任何作用(需要对 bitmap 进行优化
可能还不是很清楚,所以贴张图
质量压缩
常见的图片格式在设置在 UI 上之前需要经过解码过程
使用 RGB-565 代替 ARGB-8888 可以降低图片占用内存,上面那张图已经有了,如下红色矩形类内
内存重用
InBItmap,后面的图需 <= 第一张图的大小,下图为第二张图片重用第一张图
mCurrentBitmap 为第一张图的 Bitmap
然后小提一下 Bitmap 的内存管理
在 3.0 前,对于像素数据的支持保存在本地内存中,
在 3.0 后,像素数据和位图都储存在 Dalvik 堆中
以上为图片的储存优化,接下来介绍图片加载优化
首先要了解两个资源文件夹
mipmap 和 drawable,一般情况下,启动图标放在 mipmap 文件夹,
然后这两个文件夹的区别为 setHasMipmap 的值
mipmap 为 true,drawable 为 false
如何让 Android 图片资源适配各种分辨率的手机
先了解分辨率和 DPI ,分辨率单位为 px
1.240-320 xhdpi
2.320-480 xxhdpi !!!主流
3.480-640 xxxhdpi
下面提供两种方案
方案一:为每种 dpi 都出一套图片资源 (为设计师增加了工作量,且增大了 APK 大小)
方案二:提供一套需要支持的最大 dpi 的图片,(自动渲染的概念);
下面介绍一下图片匹配的规则(假设我的手机为 480dpi 分辨率的手机,我将需要的图片放在 xhdpi 文件夹下,系统处理如下)
- 先查找 xxhdpi 文件夹,没有找到,往下走
- 再查找 xxxhdpi 文件夹,没有找到,往下走
- 再查找 nohdpi 文件夹,如果还没有找到,才会去 xhdpi 文件夹
其中有一个问题,一个手机从不同的文件夹下拿图片,显示效果是不同的,如果不是匹配的文件夹,系统会对其图片放大或缩小
**常见的图片加载优化方法
- 异步优化:图片放在后台请求(不占用主 UI 的资源)
- 图片缓存:对于列表中的图片进行缓存(本地文件中的缓存)
- 网络请求:使用 OkHttp 进行图片请求(优点很多)
- 懒加载:当图片呈现到可视区域再进行加载**
其中图片的加载一般用多级缓存加载流程
主要原因如下
如果每次都用网络请求(服务器受不了,且浪费用户流量),需通常使用内存加本地文件两级缓存(如何单纯使用本地文件,不安全,容易被清除掉)。
小提一下超大图片加载方案
使用图片压缩来加载超大图片,会看不清图片细节
使用 BitmapRegionDecoder 来解决
下面为大家介绍一下几大图片加载的框架
1.Universal ImageLoader,优点如下
多线程,支持下载监听
bitmap 裁剪
ListView 暂停加载
自由配置
较好的控制图片的加载过程
提供在较慢的网络下对图片进行加载
2.Picasso,特点如下
缓存图片原图到本地
使用 ARGB-8888(占用内存比较大)
3.Glide(来自谷歌),特点如下
与 Activity/Fragment 生命周期一致
改变图片的大小再加载到内存
4.Fresco(来自脸谱),特点如下(重点介绍)
性能好:首次加载图片速度非常快,用户体验好
内存表现出色:有效的对内存块的图片进行了管理(共享内存机制来解决图片加载的 oom 问题)
渐进式预览:大致展示图片轮廓,然后逐渐展示清晰图片
多图请求 封装了先加载底分辨率图片,然后再显示高分辨率图片
图片呈现效果:自定义占位符,圆角图
Gif,Webp 格式
在 5.0 以下系统,Fresco 将图片放到一个特别的内存区域。当然,在图片不显示的时候,占用的内存会自动被释放。这会使得 APP 更加流畅,减少因图片内存占用而引发的 OOM。
加载 Gif 图和 WebP 动图在任何一个 Android 开发者眼里看来都是一件非常头疼的事情。每一帧都是一张很大的 Bitmap,每一个动画都有很多帧。Fresco 让你没有这些烦恼,它处理好每一帧并管理好你的内存。
以上就是大概的内容了,由于博主时间问题,会于以后写关于框架的使用及关于图片优化的小案例