Android App 性能优化之UI布局

应用UI卡顿常见原因

1. 布局Layout 复杂,无法在16ms内渲染完成,布局层次不合理,布局存在过度绘制
2. 同一时间动画执行的次数过多,导致CPU或GPU负载过重
3. 冗余资源及逻辑等导致加载和执行缓慢
4. 过度绘制

应用UI卡顿分析

1. Hierarchy Viewer
Hierarchy Viewer 是 Android Device Monitor 中内置的一种工具,可让您测量布局层次结构中每个视图的布局速度。它可以帮助您查找由视图层次结构导致的性能瓶颈。
在这里插入图片描述在这里插入图片描述
可以通过以下数据进行优化布局
渲染出该布局所需的时间
Measure:0.107 ms 测量
Layout:0.000 ms 布局
Draw:1.650 ms 绘制

  • 绿色:表示视图的渲染速度至少比一半的其他视图快。
  • 黄色:表示视图的渲染速度至少比一半的其他视图快。
  • 红色:表示视图是渲染速度最慢的那一半视图之一。

如果应用的运行速度出乎意料地慢,则红色节点可能有问题。
以下是对红色圆点的解读

  • 查找叶节点中的红色圆点或仅包含少数子级的视图组。可能会找到问题所在。应用的运行速度可能并不缓慢,或者在设备上的运行速度并不慢,需要注意这个圆点为何显示为红色。Systrace
    或 Traceview 可以提供更多信息。
  • 如果您有一个包含许多子级的视图组和一个红色测量阶段,请查看相应子级以了解它们的执行情况。
  • 带有黄色甚或红色圆点的视图在设备上的执行速度可能并不慢。这正是实际数字的用武之地。Systrace 或 Traceview 可以提供更多信息。
  • 如果层次结构的根视图具有红色测量阶段、红色布局阶段和黄色绘制阶段,那这就是一个比较典型的情况,因为它是所有其他视图的父级,并且只有在子级完成之后其布局才会完成。
  • 如果具有 20 个以上视图的树中的某个叶节点包含红色绘制阶段,则表示存在问题。请检查 onDraw() 方法中是否有不应存在的代码。

2. Lint
可以来搜索可能的视图层次结构优化机会。

在这里插入图片描述 - 使用复合可绘制对象 - 包含 ImageView 和 TextView 的 LinearLayout
作为复合可绘制对象可得到更加高效的处理。

  • 合并根框架 - 如果 FrameLayout
    是一个布局的根,并且未提供背景或内边距等信息,则可以将其替换为稍微高效一些的 merge 标记。
  • 无用的叶项 -
    没有子级或没有背景的布局通常可以移除(因为它不可见),以使布局层次结构更加扁平高效。
  • 无用的父级 - 如果一个布局含有子级但没有同级、不是
    ScrollView 或根布局且没有背景,则可以将其移除或将其子级直接移动到父级,以使布局层次结构更加扁平高效。
  • 深层布局 -
    嵌套过多的布局会降低性能。考虑使用 RelativeLayout 或 GridLayout 等比较扁平的布局来提高性能。默认的深度上限为 10。
  • 移除多余的嵌套布局-

3. Layout Inspector
Layout Inspector 可用来分析View树层级
在这里插入图片描述在这里插入图片描述

4. 通过标记重复使用布局
尽管 Android 通过各种微件来提供可重复使用的小型互动元素,但可能还需要重复使用需要特殊布局的大型组件。为了高效地重复使用完整的布局,可以使用 <include/> 和 <merge/> 标记在当前布局中嵌入其他布局。

5. 视图加载延迟
通过仅需要时加载视图来减少内存使用量并加快渲染速度。

  • 定义ViewStub

ViewStub 是一种没有任何维度的轻量型视图,它不会绘制任何内容或参与布局。因此,扩充和离开视图层次结构的成本比较低。每个 ViewStub 只需包含 android:layout 属性即可指定要扩充的布局。

以下ViewStub 适用于半透明进度条叠加层,只有当新的项目导入应用时,它才会显示。

    <ViewStub
        android:id="@+id/stub_import"
        android:inflatedId="@+id/panel_import"
        android:layout="@layout/progress_overlay"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom" />
    
  • 加载ViewStub 布局
    findViewById(R.id.stub_import).setVisibility(View.VISIBLE);
    // or
    View importPanel = ((ViewStub) findViewById(R.id.stub_import)).inflate();
    

6. 解决过度绘制

  • 移除布局中不需要的背景
  • 使视图层级结构扁平化
  • 降低透明度
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值