#阅读笔记 Android群英传-第10章-Android性能优化

学习目标:

了解Android性能优化


学习内容:

10.1 布局优化

10.1.1 Android UI渲染机制

人眼所感知的流畅画面中,需要画面的帧数达到40帧每秒到60帧每秒,最佳fps大概在60fps,这也是评价一个显卡性标准之一。在Android中、系统通过VSYNC信号触发对UI的渲染和重绘,其间隔时间是16ms(其实就是1000ms中显示60帧,所以是1000/60)。所以每次渲染逻辑都能保证在16ms内完成,用户看到的画面是会非常流畅的,若超过16ms则会出现丢帧的卡顿现象。例如一次绘制任务耗时20ms,那么16ms内VSYNC信号就无法绘制,该帧会被丢弃,等待下次信号才开始绘制,从现象来看,两帧会出现同一副画面。

10.1.2 避免Overdraw

过度绘制会浪费很多的CPU,GPU资源,例如系统默认绘制Activity的背景,而如果再给布局绘制了重叠的背景,那么默认Activity的背景就是无效的过度绘制——Overdraw。

10.1.3 优化布局层级

在Android中,系统对View进行测量、布局和绘制时,是需要对View树的遍历进行操作。若一个View树的高度太高则会严重拖慢绘制等步骤的速度,因此优化布局的一个方式就是降低View树的高度,Google在API文档中指出View树的高度不宜超过10。另外,早期的Android使用LinearLayout作为XML文件的默认根布局,而在现在的版本中使用了RelativeLayout,原因也是通过扁平的RelativeLayout减少LinearLayout嵌套所产生的树高度,从而提高UI渲染效率。

10.1.4 避免嵌套过多无用布局

1、使用<Include 标签重用Layout
2、使用<ViewStub 实现View的延迟加载
ViewStub是一个非常轻量级的组件、它不仅不可视、而且大小为0。那么重新加载显示的布局呢?
1、首先通过findViewById()找到<ViewStub 组件。
2、两种方法重新显示这个View:1) VISIBLE; 2) inflate(该方法可以返回引用的布局,从而可以通过findViewById方法来找到对应的控件)

不管使用哪种方式,一但<ViewStub 被设置为可见或者inflate了,<ViewStub 就不存在了,取而代之的是被inflate的Layout,并将这个Layout的ID重新设置为<ViewStub 中通过android:inflatedId属性所指定的ID,这也就是为什么调用两次inflate会报错的原因。

而ViewStub标签和View.GONE这种方式隐藏一个View的区别是ViewStub只会在显示时,才去渲染整个布局,而View.GONE在初始化树布局时就已经添加在布局树之上了,所以ViewStub效率更高。

10.1.5 Hierarchy Viewer

10.2 内存优化

10.2.1 什么是内存优化

由于Android应用的沙箱机制,每个应用所分配的内存大小是有限的,内存太低就会触发LMK——Low Memory Killer机制。内存分为以下几个部分:

  • 寄存器 Registers:速度最快的存储场所,因为寄存器位于处理器内部,在程序中无法控制
  • 栈 Stack:存放基本类型的数据和对象引用,但对象本身存放在堆中
  • 堆 Heap:用来存放由new创建的对象和数组。在堆中分配的内存,又JVM的GC来管理
  • 静态存储区域 Static Filed:在固定位置存放程序运行时一直存在的数据
  • 常量池 Constant Pool:常量池就是该类型所用到的常量的一个有序集合,包括直接常量(基本类型,String)和对其他类型、字段和方法的符号。

当定义一个变量,JVM就在栈中为该变量分配内存空间,当该变量的作用域结束后,这部分内存空间就会马上被用作新的空间,当该变量作用域结束之后,这部分内存空间会马上被用作新的空间进行分配。如果使用new的方式创建一个变量,那么就会在堆中为这个对象分配内存空间,即使该对象的作用域结束,这部分内存不会被立即回收而是等待系统GC。

10.2.2 获取Android系统内存信息

10.2.3 内存回收

Java相比C和C++最大的优势就是不用手动管理系统资源,Java创建了垃圾收集线程来自动进行资源整理。但是也无法避免部分对象忘记回收的现象从而造成内存泄漏。

10.2.4 内存优化实例

10.2.4.1 Bitmap优化

是造成内存OOM的最大威胁,下面给出一些使用技巧

  • 使用适当分辨率和大小的图片
    由于Android系统做资源适配时会对不同的分辨率文件夹下的图片进行缩放来适配相应的分辨率。如果图片分辨率与资源文件夹分辨率不匹配时,就会导致系统消耗更多资源。
  • 及时回收内存
    一旦使用Bitmap之后,需要及时回收recycle()释放内存资源。自Android3.0之后由于Bitmap被放置到了堆中,其内存由GC来管理,不需要进行释放。
  • 使用图片缓存
    内存缓存LruCache和硬盘缓存DiskLruCache
10.2.4.2 代码优化
  • 对常亮使用static修饰符
  • 使用静态方法,静态方法会比普通方法提高15%左右的访问速度
  • 减少不必要的成员变量和对象
  • 尽量不使用枚举和迭代器
  • 对Cuesor、Reciever、Sensor、File等对象、注意对他们的创建、回收与注册、解注册
  • 尽量避免IOC框架,IOC通常使用注解反射来实现,大量反射会带来性能下降
  • 使用RenderScript、OpenGL来进行非常复杂的绘图操作
  • 使用SurfaceView来代替View进行大量频繁的绘图操作
  • 尽量使用视图缓存,而不是每次都执行inflate()的方法解析视图

其他:使用工具来进行分析优化
3、 Lint工具
4、 使用Memory Monitor工具
5、使用TraceView 工具优化APP性能
6、使用MAT工具分析APP内存状态
7、使用Dumpsys命令分析系统状态


学习时间:

2022/2/7

学习产出:

一篇技术博客
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值