布局优化
界面布局会对应用程序的性能产生影响,如果布局写得糟糕的话,那么程序加载UI的速度就会非常慢,从而造成不好的用户体验。
measure、layout、draw这三个过程都包含自顶向下的View Tree遍历耗时,如果视图层级太深自然需要更多的时间来完成整个绘测过程,从而造成启动速度慢、卡顿等问题。而onDraw在频繁刷新时可能多次出发,因此onDraw更不能做耗时操作,同时需要注意内存抖动。对于布局性能的检测,可以使用systrace与traceview按照绘制流程检查绘制耗时函数。
层级优化
-
层级查看
使用Layout Inspector分析布局层级(app需为debug包)。
Android studio 提供了Layout Inspector,位于顶部工具栏>Tools>Layout Inspector
-
优化建议
- 合理使用include标签,复用布局
- 合理减少布局层级,使用merge标签
- 合理延迟inflater非必须布局,使用ViewStub标签
过度绘制
过度绘制是指系统在渲染单个帧的过程中多次在屏幕上绘制某一个像素。例如,如果我们有若干界面卡片堆叠在一起,每张卡片都会遮盖其下面一张卡片的部分内容。但是,系统仍然需要绘制堆叠中的卡片被遮盖的部分。
-
GPU过度绘制检查
打开手机开发者选项,打开调试GPU过度绘制选项。
打开需要检查的应用,会有蓝色、绿色、粉色、红色标注不同的绘制程度,粉色、红色表示过度绘制层级较深,应尽量避免
-
解决方案
- 移除布局中不需要的背景
- 使视图层次结构扁平化
布局异步加载
android提供了asynclayoutinflater把耗时的加载操作在异步线程中完成,最后把加载结果再回调给主线程。
implementation "androidx.asynclayoutinflater:asynclayoutinflater:1.0.0"
new AsyncLayoutInflater(this).inflate(R.layout.activity_main,
null,
new AsyncLayoutInflater.OnInflateFinishedListener() {
@Override
public void onInflateFinished(@NonNull View view, int resid, @Nullable ViewGroup parent) { setContentView(view); //......
} });
1、使用异步 inflflate,那么需要这个 layout 的 parent 的 generateLayoutParams 函数是线程安全的;
2、所有构建的 View 中必须不能创建 Handler 或者是调用 Looper.myLooper;(因为是在异步线程中加载的,异
步线程默认没有调用 Looper.prepare );
3、AsyncLayoutInflflater 不支持设置 LayoutInflflater.Factory 或者 LayoutInflflater.Factory2;
4、不支持加载包含 Fragment 的 layout
5、如果 AsyncLayoutInflflater 失败,那么会自动回退到UI线程来加载布局