美文网首页
三. Android 布局优化

三. Android 布局优化

作者: perry_Fan | 来源:发表于2019-05-10 16:13 被阅读0次

    1. Android绘制原理及工具选择

    1.1 绘制分析

    CPU:负责计算显示内容。视图的创建,布局计算,图片解码,文本绘制。
    GPU:负责栅格化操作(UI元素绘制到屏幕上),Button拆分成像素。换算成纹理。
    16ms 发出VSync信号出发 UI 渲染。
    大多数的Android设备屏幕刷新频率:60HZ

    1.2 优化工具

    Systrace

    关注Frames
    正常:绿色圆点,丢帧:黄色或红色
    Alerts栏。自动分析异常性能分析的一些条目

    Layout Inspector

    查看视图层次结构

    Choreographer(API16以后)

    获取FPS,线上使用,具备实时性

    Choreographer.getInstance().postFrameCallback

    2. Android布局加载原理

    深入布局加载源码:

    setContentView -> LayoutInflater -> inflate -> getLayout -> createViewFromTag -> Factory -> createView -> 反射

    性能瓶颈
    布局文件解析:IO过程。布局特别大,文件也就特别大,io也就会卡顿。
    创建View对象:反射。反射使用过多(标签过多)导致反射很慢。

    LayoutInflater.Factory
    LayoutInflater 创建View的一个Hook
    定制创建View的过程:全局替换自定义TextView等
    LayoutInflater当中的 Factory与Factory2
    Factory2继承于Factory
    多了一个参数:parent

    3. 优雅获取界面布局耗时

    3.1 常规方式

    获取每个界面的加载耗时。
    实现:复写setContentView、手动埋点。不够优雅,代码有侵入性。

    3.2 AOP/ArtHook

    找到切面点。切Activity的setContentView。

    @Around("execution(* android.app.Activity.setContentView(..))")

    call表示切在方法调用的部分。execution表示切在方法的里面

    获取任一控件的加载耗时 ,在内部和执行方法处和启动时间计算方式一致。
    低侵入性。
    LayoutInflater.Factory

    3.3 异步Inflate实战

    布局文件读取过程慢,IO过程
    创建view过程慢,反射过程创建,比new慢3倍。

    根本性解决。不使用反射/IO
    侧面缓解。

    AsyncLayoutInflater(异步Inflater)

    • WorkThread加载布局
    • 回调主线程
    • 节约主线程时间

    导包:

    com.android.support:asynclayoutinflater

    4. 布局加载优化实战

    AsyncLayoutInflater只是缓解。
    Java代码写布局,它的缺点是不便于开发、可维护性差。
    X2C框架(通过APT编译器翻译XML为Java代码)
    开发人员写XML,加载Java代码。

    annotationProcessor 'com.zhangyue.we:x2c-apt:1.1.2'
    implementation 'com.zhangyue.we:x2c-lib:1.0.6'

    用到的页面使用:@Xml(layouts = "activity_main")
    问题:部分属性Java不支持、失去了系统的兼容(AppCompat)

    5. 视图绘制优化实战

    优化布局层级及复杂度
    测量:确定大小
    布局:确定位置
    绘制:绘制视图

    性能瓶颈:每个阶段耗时。自顶向下遍历。触发多次。
    准则:减少View树层级。

    宽而浅,避免窄而深

    (布局层级 从上往下叫宽度,所有元素尽可能在一个ViewGroup当中)
    (布局深度尽可能更浅)

    1)ConstrainLayout:实现几乎完全扁平化布局。构建复杂布局性能更高。具有RelativeLayout和LinearLayout的特性
    2)不嵌套使用RelativeLayout
    3)不在嵌套LinearLayout中使用weight
    4)merge标签:减少一个层级,只能用于根View

    过度绘制

    一个像素最好只会被控制一次。
    5)调试GPU过度绘制(开发者模式中打开)
    蓝色可接受
    避免过度绘制方法

    6)去掉多余背景色,减少复杂shape使用
    7)避免层级叠加
    8)自定义View使用 clipRect 屏蔽被遮盖View绘制
    9)ViewStub:高效占位符、延迟初始化
    10)onDraw中避免:创建大对象、耗时操作。
    11)TextView优化

    6. 总结

    用到了哪些工具?
    结构化思维。使用了很多工具,有不同的使用场景。
    1)Choreographer 可以带到线上,得到帧率。
    2)每个布局耗时 AOP、HOOK
    3)线下开发环节、Systrace、Layout Inspector
    4)布局为什么会导致卡顿,你又是如何优化的?
    5)IO、反射、遍历、重绘
    6)异步Inflate、X2C、减少层级、重绘
    7)AOP、监控
    8)做完布局优化后有哪些成果产出?
    9)体系化监控手段:线下 + 线上

    指标:FPS、加载时间、布局层级
    核心路径保障

    相关文章

      网友评论

          本文标题:三. Android 布局优化

          本文链接:https://www.haomeiwen.com/subject/wttryqtx.html