不断学习,做更好的自己!💪
视频号CSDN简书欢迎打开微信,关注我的视频号:程序员朵朵点我点我 前言什么是性能
快(流畅的体验) 稳(稳定) 省(省电/流量) 小(安装包小) 这四点很形象的代表了性能的四个方面,同时也让我们知道我们 App 现在是否是款性能良好的 APP,如果有一项不达标,那么说明我们的应用有待优化。
过度绘制 定义过度绘制(Overdraw):指的是屏幕上的某个像素在同一帧的时间内被绘制了多次。
检测Android手机上面的开发者选项提供了工具来检测过度绘制,可以按如下步骤来打开: 开发者选项->调试GPU过度绘制->显示过度绘制区域
注意: 有些过度绘制是无法避免的。因此在优化界面时,应该尽量让大部分的界面显示为真彩色(即无过度绘制)或者为蓝色(仅有 1 次过度绘制)。尽量避免出现粉色或者红色。
优化1. 移除布局中不需要的背景
- 移除 Window 默认的 Background 方式一:在theme中设置
@null
方式二:在Activity的onCreate()方法中添加:
getWindow().setBackgroundDrawable(null);
- 移除控件中不需要的背景
2. 将layout层级扁平化
- Layout Inspector来查看layout的层次结构。 在Android Studio中点击 Tools > Android > Layout Inspector。然后在出现的 Choose Process 对话框中,选择想要检查的应用进程即可。 Layout Inspector会自动捕获快照,然后会显示以下内容:
- View Tree:视图在布局中的层次结构。
- Screenshot:每个视图可视边界的设备屏幕截图。
- Properties Table:选定视图的布局属性。
- 使用嵌套少的布局 我们可以使用 LinearLayout 和 RelativeLayout 来完成。但是 LinearLayout 相比于 RelativeLayout,就多了一层,所以 RelativeLayout 明显是一个更优的选择。
- 使用 include 标签能够复用布局 可以将一个指定的布局文件加载到当前的布局文件中。如下:
...
需要注意的是,如果include标签指定了layout_*这种属性,那么要求 android:layout_width和android:layout_height必须存在,否则其他的android:layout_*形式的属性无法生效。
- 使用 merge 标签减少嵌套
一般和include标签一起使用从而减少布局的层级。在上述示例中,由于当前布局是一个竖直方向的LinearLayout,用过merge标签就可以去掉多余的那一层LinearLayout。如下:
ViewStub ViewStub继承了View,它非常轻量级且宽和高都是0,因此它本身不参与任何的布局和绘制过程。比如:网络异常时的界面,这个时候就没有必要在整个界面初始化将其加进来,通过ViewStub就可以做到在使用的时候再加载,提高了程序初始化的性能:
panel_import是@layout/layout_empty_txt这个布局的根元素的id。 在需要加载ViewStub中的布局时,可以按照如下两种方式:
(ViewStub)findViewById(R.id.stub_import).setVisibility(View.VISIBLE);
或者
View mImportPanel = ((ViewStub)findViewById(R.id.stub_import)).inflate();
通过上述两个方法加载后,ViewStub就会被它内部的布局替换掉,这个时候ViewStub就不再是整个布局结构中的一部分了。
- 使用lint来优化布局的层次结构 lint是一个静态代码分析工具,可以用来协助优化布局的性能。要使用lint,点击Analyze> Inspect Code即可。
布局性能方面的信息位于Android> Lint> Performance下,我们可以点开它来看下一些优化建议。 下面是lint的一些优化技巧:
- 使用复合图片 如果一个线性布局中包含一个 ImageView 和一个 TextView,可以使用复合图片来替换掉
- 合并根节点 如果一个FrameLayout 是整个布局的根节点,并且也没有提供背景、留白等等,那么可以使用标签来替换掉,因为DecorView本身就是一个FrameLayout。
- 移除布局中无用的叶子 布局是一个树形的结构,如果一个布局没有子 View 或者背景,那么可以把它移除掉(这布局本身就不可见了)。
- 移除无用的父布局 如果一个布局没有兄弟,也不是ScrollView 或者根 View,并且也没有背景,那么可以把这个父布局移除掉,然后把它的子view移到它的父布局下。
- 避免过深的层次结构 过多的布局嵌套不利于性能,可以使用更扁平化的布局,如RelativeLayout、GridLayout、ConstraintLayout等布局来提高性能。布局默认的最大深度为10。
- 如果父控件有颜色,也是自己需要的颜色,那么就不必在子控件加背景颜色
- 如果每个自控件的颜色不太一样,而且可以完全覆盖父控件,那么就不需要再父控件上加背景颜色
- 尽量减少不必要的嵌套
- 能用
LinearLayout
和FrameLayout
,就不要用RelativeLayout
,因为RelativeLayout
控件相对比较复杂,测绘也想要耗时。 - 使用
include
和merge
增加复用,减少层级 ViewStub
按需加载,更加轻便- 复杂界面可选择
ConstraintLayout
,可有效减少层级