接下来说明一下关于其他内存问题。图片问题,作为一个优秀的Android开发者,在图片的类型选择,图片显示前的处理都是要好好考虑的,因为不同类型图片在Android中的显示代价是不同的,使用不同显示方式代价也是不同的,首先看一下图片类型png与jpg两种类型显示代价有不同,原因在于png占的内存较多,但解码叫简单,若png图片过多,会容易垃圾回收,甚至内存溢出,而jpg的内存小,但解码复杂,会花更多时间解码,所以要根据具体情况来定,如果当前是由于内存问题导致垃圾回收频繁执行导致卡慢顿,这样图片优化就减少png,如果是非内存问题导致的,就可以使用png。

谷歌官方说法如下:

Smaller PNG Files(较少的png文件)

尽量减少PNG图片的大小是Android里面很重要的一条规范。相比起JPEG,PNG能够提供更加清晰无损的图片,但是PNG格式的图片会更大,占用更多的磁盘空间。到底是使用PNG还是JPEG,需要设计师仔细衡量,对于那些使用JPEG就可以达到视觉效果的,可以考虑采用JPEG即可。

谷歌官方这样说应该是由于Android上导致卡慢顿的大多数原因是和内存有关吧。

关于在图片显示前的操作:

Pre-scaling Bitmaps(预放缩图片)

对bitmap做缩放,这也是Android里面最遇到的问题。对bitmap做缩放的意义很明显,提示显示性能,避免分配不必要的内存。Android提供了现成的bitmap缩放的API,叫做createScaledBitmap(),使用这个方法可以获取到一张经过缩放的图片。

上面的方法能够快速的得到一张经过缩放的图片,可是这个方法能够执行的前提是,原图片需要事先加载到内存中,如果原图片过大,很可能导致OOM。下面介绍其他几种缩放图片的方式。

inSampleSize能够等比的缩放显示图片,同时还避免了需要先把原图加载进内存的缺点。我们会使用类似像下面一样的方法来缩放bitmap:

另外,我们还可以使用inScaled,inDensity,inTargetDensity的属性来对解码图片做处理,源码如下图所示:

(注:这里的bitmapoption还可以知道图片的编码类型)

还有一个经常使用到的技巧是inJustDecodeBounds,使用这个属性去尝试解码图片,可以事先获取到图片的大小而不至于占用什么内存。如下图所示:

Re-using Bitmaps(重复使用bitmaps)

我们知道bitmap会占用大量的内存空间,这节会讲解什么是inBitmap属性,如何利用这个属性来提升bitmap的循环效率。前面我们介绍过使用对象池的技术来解决对象频繁创建再回收的效率问题,使用这种方法,bitmap占用的内存空间会差不多是恒定的数值,每次新创建出来的bitmap都会需要占用一块单独的内存区域,如下图所示:

为了解决上图所示的效率问题,Android在解码图片的时候引进了inBitmap属性,使用这个属性可以得到下图所示的效果:

使用inBitmap属性可以告知Bitmap解码器去尝试使用已经存在的内存区域,新解码的bitmap会尝试去使用之前那张bitmap在heap中所占据的pixel data内存区域,而不是去问内存重新申请一块区域来存放bitmap。利用这种特性,即使是上千张的图片,也只会仅仅只需要占用屏幕所能够显示的图片数量的内存大小。下面是如何使用inBitmap的代码示例:

使用inBitmap需要注意几个限制条件:

·在SDK 11 -> 18之间,重用的bitmap大小必须是一致的,例如给inBitmap赋值的图片大小为100-100,那么新申请的bitmap必须也为100-100才能够被重用。从SDK 19开始,新申请的bitmap大小必须小于或者等于已经赋值过的bitmap大小。

·新申请的bitmap与旧的bitmap必须有相同的解码格式,例如大家都是8888的,如果前面的bitmap是8888,那么就不能支持4444与565格式的bitmap了,不同的编码格式占用的内存是不同的,有时候也可以根据需求指定编码格式。

我们可以创建一个包含多种典型可重用bitmap的对象池,这样后续的bitmap创建都能够找到合适的“模板”去进行重用。如下图所示:

Google介绍了一个开源的加载bitmap的库:Glide,这里面包含了各种对bitmap

前面提到编码方式,其实不同的编码方式占用内存是不同的当然显示效果也是有区别的,可以在不影响用户体验的前提下,适当选择编码方式。

Smaller Pixel Formats

常见的png,jpeg,webp等格式的图片在设置到UI上之前需要经过解码的过程,而解压时可以选择不同的解码率,不同的解码率对内存的占用是有很大差别的。在不影响到画质的前提下尽量减少内存的占用,这能够显著提升应用程序的性能。

Android的Heap空间是不会自动做兼容压缩的,意思就是如果Heap空间中的图片被收回之后,这块区域并不会和其他已经回收过的区域做重新排序合并处理,那么当一个更大的图片需要放到heap之前,很可能找不到那么大的连续空闲区域,那么就会触发GC,使得heap腾出一块足以放下这张图片的空闲区域,如果无法腾出,就会发生OOM。如下图所示:

所以为了避免加载一张超大的图片,需要尽量减少这张图片所占用的内存大小,Android为图片提供了4种解码格式,Android默认是使用argb8888格式,还有argb4444,alpha8及rgb565:

对于不同解码格式占用内存大小具体如下:

Bitmap.Config ARGB_4444:每个像素占四位,即A=4,R=4,G=4,B=4,那么一个像素点占4+4+4+4=16位

Bitmap.Config ARGB_8888:每个像素占四位,即A=8,R=8,G=8,B=8,那么一个像素点占8+8+8+8=32位

Bitmap.Config RGB_565:每个像素占四位,即R=5,G=6,B=5,没有透明度,那么一个像素点占5+6+5=16位

Bitmap.Config ALPHA_8:每个像素占四位,只有透明度,没有颜色。

一般情况下我们都是使用的ARGB_8888,由此可知它是最占内存的,因为一个像素占32位,8位=1字节,所以一个像素占4字节的内存。假设有一张480x800的图片,如果格式为ARGB_8888,那么将会占用1500KB的内存。

随着解码占用内存大小的降低,清晰度也会有损失。我们需要针对不同的应用场景做不同的处理,大图和小图可以采用不同的解码率。在Android里面可以通过下面的代码来设置解码率:

实际上,一张图片在内存中占用多大空间主要受图片本身大小(分辨率),解码方式,还有就是设备像素密度这三个因素影响,其中像素密度是由设备定的,编程人员可控性不高。所以解决一张图片在内存中大小问题,就得从图片分辨率和解码方式入手。

注意:

Bitmap 对象在不使用时,我们应该先调用recycle()释放内存,然后才置空,因为加载bitmap对象的内存空间,一部分是java的,一部分是c的(因为Bitmap分配的底层是通过jni调用的,BitMap底层是skia图形库,skia图形库是c实现的,通过jni的方法在java层进行封装)。这个recycle()函数就是针对c部分的内存释放。

Android App 性能优化之图片优化相关推荐

  1. Android APP性能优化

    转载自:https://www.cnblogs.com/qwangxiao/p/8727229.html Android APP性能优化(最新总结) 导语 安卓大军浩浩荡荡,发展已近十个年头,技术优化 ...

  2. Android APP性能优化(一)

    Android APP性能优化(最新总结) 安卓大军浩浩荡荡,发展已近十个年头,技术优化日异月新,如今Android 8.0 Oreo 都发布了,Android系统性能已经非常流畅了.但是,到了各大厂 ...

  3. 十大技巧优化Android App性能

    无论锤子还是茄子手机的不断冒出,Android系统的手机市场占有率目前来说还是最大的,因此基于Android开发的App数量也是很庞大的.那么,如何能开发出更高性能的Android App?相信是软件 ...

  4. Android 应用性能优化(4)---Android App性能评测分析-启动时间篇

    Android App性能评测分析-启动时间篇 1.前言 随着项目版本的迭代,App的性能问题会逐渐暴露出来,而好的用户体验与性能表现紧密相关,性能问题从应用的启动优化开始,下面会根据实际app性能测 ...

  5. Android App性能优化十技巧

    无论锤子还是茄子手机的不断冒出,Android系统的手机市场占有率目前来说还是最大的,因此基于Android开发的App数量也是很庞大的.那么,如何能开发出更高性能的Android App?相信是软件 ...

  6. Android App 性能优化系列结语篇

    Android App 性能优化系列结语篇 原文出处:http://gold.xitu.io/post/581f4ad667f3560058a33057 关于Android App的优化, 从第一篇的 ...

  7. Android App性能优化系列

    Android App性能优化系列 关于Android App的优化,从第一篇的计划开始,到内存优化的系列文结束,不知不觉近三个月的时间,写了十五六篇相关的博文,算是对自己的知识的一个系统化,也希望能 ...

  8. Android App 性能优化总结

    Android App 性能优化系列结语篇 转发自:http://blog.lmj.wiki/2016/11/06/app-opti/app_opt_summary/#more 关于Android A ...

  9. Android App 性能优化之稳定性

    Android App性能优化之稳定性问题分类 1. ANR 2. Crash 3. 应用退出 1. ANR ANR(Application Not Responding 应用程序无响应) 1.1大致 ...

  10. 优化Android App性能?十大技巧

    优化Android App性能?十大技巧 android shangxuetang 1年前 (2014-05-27) 3399℃ 4评论 android 无论锤子还是茄子手机的不断冒出,Android ...

最新文章

  1. Numpy入门教程:09. 输入和输出
  2. 技术19期:1分钟入门数据治理!必看!【技术篇】
  3. [Nova ERROR] InternalError: Nova requires QEMU version 2.5.0 or greater.
  4. 作为SEO老人不轻易建议客户进行动态网页优化设置
  5. 【Groovy】json 序列化 ( 类对象转为 json 字符串 | 使用 JsonBuilder 进行转换 | 使用 JsonOutput 进行转换 | 将 json 字符串格式化输出 )
  6. Java黑皮书课后题第7章:7.2(倒置输入的数)编写程序,读取10个整数,然后按照和读入顺序相反的顺序将它们显示出来
  7. SQLServer中批量插入数据方式的性能对比 (转)
  8. leetcode 995. K 连续位的最小翻转次数(贪心算法)
  9. dlopen失败一例:路径字串多一个回车,导致文件找不到
  10. pytorch BCELoss()、KLDivLoss()的参数 及 “对于size_average、reduce、reduction参数的研究”
  11. 内核源码编译ko文件如何调用math.h_第八期-Linux内核编程环境(2)
  12. AOP设计与原理(连接点,切入点与代理模式)——Spring AOP(二)
  13. 单片微机原理与接口技术——8051汇编指令系统与编程基础(2)数据传送指令
  14. 云端服务器的建立和登录(3.7)
  15. 八百呼的录音话机能解决企业的客户纠纷
  16. AutoFac在WinForm中的使用
  17. 青浦区专利工作试点和示范企业给予20万元和30万元奖励
  18. 每月一书(202107):《曾国藩的正面与侧面》
  19. python爬虫日记01
  20. 我的项目部署到阿里云怎么就那么难?

热门文章

  1. 联想拯救者15isk清灰_拯救者15值得买吗?联想拯救者15isk游戏本全面深度评测图解...
  2. KubernetesAPI审计日志方案
  3. mac m1 解决fatal: unable to access ‘https://github.com/Homebrew/homebrew-core/‘ ;同时指定intel架构的brew 版本
  4. C语言 | 位域的使用详解
  5. Unity3D 学习笔记6 ——协程
  6. 使用for循环打印星星
  7. Acer TravelMateP249主板上最容易被人忽略的問題
  8. 长荣航空空服员受辱追踪:工会盼给当事人公伤假
  9. 频点、带宽、FFT点数、采样率的关系
  10. oracle 11g duplicate database基于备份复制数据库(一)