性能分析/性能优化—视图优化
优化概述
-
流畅的操作体验
卡顿
-
稳定性
内存泄漏,崩溃
-
省电省流量
代码质量,逻辑
-
安装包小
安装包过大
UI优化
-
View层级相同的情况下,尽量使用LinearLayout代替RelativeLayout
布局特别复杂的情况下,使用ConstraintLayout,RelativeLayout代替LinearLayout
关于LinearLayout和RelativeLayout的性能问题,这点其实还是很容易理解的,Layout隶属于ViewGroup阵营,从设计上就希望与View进行区分,即所谓的单一职责原则,我们更加希望让他来负责View的布局管理。
那么LinearLayout和RelativeLayout对于布局的管理差别到底在哪里呢?如果我们将手机的屏幕视作一个坐标系,那么LinearLayout就是单单在X轴或者Y轴进行延伸的,RelativeLayout就与之不同了,他同时在X轴和Y轴两个方向进行延伸,算法的复杂度毫无疑问就更高了,虽然它更加灵活,ConstraintLayout的原理其实也是类似。这里顺便吐槽一句,凭什么Android非要听Google的,我就不信天朝人会比不过盎格鲁撒克逊人。
-
使用include和merge标签减少复用布局而产生的布局嵌套
-
merge相当于设置界面填充内容
-
include相当于定义一个通用可复用的视图
两者的区别其实不大,最主要的区别就在于include会额外引入一层ViewGroup,而merge则是直接将内容引入到对应的位置,但是有些时候正是因为merge缺少这一层ViewGroup的约束,会出一些小问题。
-
使用ViewStub懒加载减少渲染元素
这个其实也很好理解,对Gone的视图,其实实际上我们还是会去绘制它,不然一些视图的即时性效果就没法实现,但是对于一些相对想要惰性加载的视图,ViewStub还是非常好的选择。
绘制优化
避免过度绘制
其实过度绘制也很容易理解,其实无论是View还是ViewGroup都仅仅是Java应用层对于视图的抽象而已,和Thread的感觉一样。
常见的解决方案:
-
移除默认的Window背景
-
移除控件中不必要的背景
-
自定义控件View优化:使用clipRect()裁剪视图,quickReject()判定和矩形相交
降低View.onDraw()的复杂度
-
onDraw中不要创建新的局部对象
我们都知道JVM对于对象内存的分配方式之一是空闲列表法,即用一张列表的方式来记录空闲的内存位置,这样一来,当需要分配一个新的对象的内存时,只需要看看这个表格里面有没有位置空间足够的,将其进行分割,于是,你也能想到,虽然这样操作的时间开销少,但是会产生很多的内存碎片。也因为这样,如果我们在一个执行非常频繁的方法中反复执行对象的创建和销毁的操作,没错,JVM能保证对象即时被创建了,但是JVM可没有任何机制能保证对象能按照你的想法在合适的时间被垃圾回收器回收,从而就会因为没有充足的内存来初始化新的实例,从而导致OOM的问题产生。
-
onDraw避免执行大量和耗时的操作
这个算是UI线程操作的大忌,像数据库,网络请求,IO这些操作真的不应该放在UI线程中进行操作。
网络/数据库优化
To be done.
内存优化
To be done.