写点什么

90% 的开发者都不知道的 UI 本质原理和优化方式,android 开发实例实验报告

作者:嘟嘟侠客
  • 2021 年 11 月 26 日
  • 本文字数:2416 字

    阅读完需:约 8 分钟

所谓 UI 优化,就是拆解渲染过程的耗时,找到瓶颈的地方,加以优化。


前面分析了 UI 原理,Activity、Window、DecorView、ViewRootImpl 之间的关系,以及 XML 布局文件是如何解析成 View 对象的。


耗时的地方:


  • View 的创建在主线程,包括 measure、layout、draw,界面复杂的时候,这一部分可能会很耗时。

  • 解析 XML,反射创建 VIew 对象,这一过程的耗时。


下面介绍一些常用的 UI 优化方式~

3.1 常规方式

  1. 减少 UI 层级、使用 merge、Viewstub 标签优化

  2. 优化 layout 开销、RelativeLayout 和带有 weight 的 Linearlayout 会测量多次,可以尝试使用 ConstraintLayout 来代替。

  3. 背景优化,分析 DecorView 创建的时候,发现 DecorView 会设置一个默认背景,可以统一将 DecorView 背景设置为通用背景,其它父控件就无需设置背景,避免重复绘制。

3.2 xml 转换成代码

使用 xml 编写布局,很方便,但是最终要通过 LayoutInflater 的 inflate 方法,将 xml 解析出来并递归+反射去创建 View 对象,布局比较复杂的时候,这一部分会非常耗时。


使用代码创建可以减少 xml 递归解析和反射创建 View 的这部分耗时。 当然,如果将 xml 都换成代码来写,开发效率将不忍直视,并且代码可读性也是个问题。


掌阅开源的一个库,编译期自动将 xml 转换成 java 代码,X2C


它的原理是采用 APT(Annotation Processor Tool)+ JavaPoet 技术来完成编译期间【注解】-【解注解】->【翻译 xml】->【生成 java】整个流程的操作


即在编译生成 APK 期间,将需要翻译的 layout 翻译生成对应的 java 文件,这样对于开发人员来说写布局还是写原来的 xml,但对于程序来说,运行时加载的是对应的 java 文件。



侵入性极低,去除注解则回退到原生的运行时解析方式。当然,有些情况是不支持转换的,比如 merge 标签,编译期没法确定它的 parent。

3.3 异步创建 View

通过子线程创建 View,减少主线程耗时。


private void threadNewView() {


new Thread(){


@Override


public void run() {


mSplashView = LayoutInflater.from(MainActivity.this).inflate(R.layout.activity_splash,null);


}


}.start();


}


当然,这种方式需要处理同步问题,并且没有从源头上解决创建 View 耗时,只是将这部分耗时放到线程去做。UI 更新的操作还是要切换到主线程,不然会触发 ViewRootImpl 的 checkThread 检测。


void checkThread() {


if (mThread != Thread.currentThread()) {


throw new CalledFromWrongThreadException(


"Only the original thread that created a view hierarchy can touch its views.");


}


}

3.4 复用 View

复用 View 这个应该比较常见了,像 RecyclerView 的四级缓存,目的就是通过复用 View 减少创建 View 的时间。


我们可以在 onDestroy 方法将 View 的状态清除,然后放入缓存。在 onCreate 的时候去命中缓存,设置状态。


3.5 异步布局: Litho

正常情况下 measure、layout、draw 都是在主线程执行的,最终绘制操作是在 draw 方法,而 measure、layout 只是做一些数据准备,完全可以放到子线程去做。


Litho 的原理就是将 measure、layout 放到子线程: github.com/facebook/li…



优点:


  1. 将 measure、layout、放到子线程去做,减少主线程耗时。

  2. 使用自己的布局引擎,减少 View 层级,界面扁平化。

  3. 优化 RecyclerView,提高缓存命中率。


缺点:


  1. 无法在 AS 中预览。

  2. 使用自己的布局引擎,有一点的使用成本。

3.6 Flutter:自绘引擎

Flutter 是一个跨平台 UI 框架,内部集成了 Skia 图像库,自己接管了图像绘制流程,性能直逼原生,是时候制定计划学习一波了~




学习的过程中善于总结才能快速提升个人的水平,这里我也总结了一份《Android 性能优化全方面解析》,1586 页,5 个章节,95 个小点,不仅仅有详细的底层原理的解析,还有大厂性能优化探索与实践!


第一章 性能优化心得与经验


  • 移动端性能监控方案 Hertz

  • Android 性能优化之虚拟机调优

  • Android UI 性能优化

  • 美团外卖 Android Lint 代码检查实践

  • 使用 Android Studio 和 MAT 进行内存泄漏分析



第二章 响应速度


  • Android App 启动优化全记录

  • Android 中如何计算 App 的启动时间?

  • 应用启动时间

  • 支付宝 App 构建优化解析

  • Redex 初探与 Interdex:Andorid 冷启动优化



第三章 流畅度


  • Android 中的卡顿丢帧原因概述

  • Android 无障碍服务导致的整机卡顿案例分析

  • 显示性能指标

  • 渲染速度缓慢

  • Android 流畅度检测原理简析



第四章 内存


  • Android 中低内存对性能的影响

  • Android OOM 案例分析

  • Android 代码内存优化建议

  • Android 匿名共享内存(Ashmem)原理

  • Linux 查看进程消耗内存情况总结



第五章 图形栈


  • Android 中的 Hardware Layer 详解

  • Android 硬件加速原理与实现简介

  • Android 图形系统概述

  • Choreographer 原理

  • SurfaceFlinger 启动篇

  • Android 应用程序 UI 硬件加速渲染技术




还有一份《360°全方面性能调优》一共有 721 页,四个章节,25 个小点。


1、设计思想与代码质量优化


2、程序性能优化


  • 启动速度与执行效率优化

  • 布局检测与优化

  • 内存优化

  • 耗电优化

  • 网络传输与数据储存优化

  • APK 大小优化


3、开发效率优化


  • 分布式版本控制系统 Git

  • 自动化构建系统 Gradle

总结

写到这里也结束了,在文章最后放上一个小小的福利,以下为小编自己在学习过程中整理出的一个关于 Flutter 的学习思路及方向,从事互联网开发,最主要的是要学好技术,而学习技术是一条慢长而艰苦的道路,不能靠一时激情,也不是熬几天几夜就能学好的,必须养成平时努力学习的习惯,更加需要准确的学习方向达到有效的学习效果。由于内容较多就只放上一个大概的大纲,需要更及详细的学习思维导图的还有高级 UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter 全方面的 Android 进阶实践技术资料,并且还有技术大牛一起讨论交流解决问题。


![跨平台开发:Flutter.png](https://upload-images.jianshu.io/uplo


《Android 学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》

【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享


ad_images/15233854-eaa02fcafa73e0af.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

用户头像

嘟嘟侠客

关注

还未添加个人签名 2021.03.19 加入

还未添加个人简介

评论

发布
暂无评论
90%的开发者都不知道的UI本质原理和优化方式,android开发实例实验报告