浅谈Android的流畅性优化——案例分享

简介: 学习了前文的归因分析,本篇文章就带大家以实际的案例进行浅要的分析和给出具体的优化策略,具体的案例来自于网络,如有错误,还请指出。

前置知识

前言

学习了前文的归因分析,本篇文章就带大家以实际的案例进行浅要的分析和给出具体的优化策略,具体的案例来自于网络,如有错误,还请指出。

前文回顾

前文中,我们讲到了流畅性优化中一个布局从 xml 到成为一个 View 对象有哪些耗时的问题。我们可以回顾一下,如下图,我们可以把上文中 View 对象的创建以及其渲染等耗时问题分为以下的三点,包括 UI 构建数据绑定 以及 View 的显示。对于上述这三点,我们可以逐个进行优化。

1.webp.jpg

UI 构建

UI 的构建问题中,我们有遇到诸如:载入 XML 的 IO 问题、class 的反射问题、创建 View 的问题、Asset 大锁问题。这些耗时都是由于在主线程中发生,所以导致其影响我们的流畅性。对此,Google 有提出一种异步加载布局的方案:AsyncLayoutInflater

  • AsyncLayoutInflater 解决方案
    这个方案可以对布局进行异步的加载,其可以应用在提前知晓布局的显示,以及对布局显示的速度没有要求的情况下进行使用。例如弹窗布局放置于异步操作就没有问题,它可以提前在异步准备好操作。但是这类解决方案的劣势即是无法即时响应,且我们没有那么多情况下是可以提前知晓、准备好布局的展示。
// 异步加载 xml, 在 Activity.onCreate(xxx) 里面
AsyncLayoutInflater(this).inflate(R.layout.activity_try_everything, null, object : AsyncLayoutInflater.OnInflateFinishedListener {
      override fun onInflateFinished(view: View, p1: Int, p2: ViewGroup?) {
           setContentView(view)
      }
})
复制代码
  • 所以说,这个 Google 的方案是不能适用于我们大部分的使用场景的,下面我们可以看一下抖音的优化方案。
  • 抖音的解决方案
  • 使用 X2C 解决 xml 的性能问题。
    直接把 xml 在编译阶段转化为 java 代码,这样就无需访问 IO 做反射生成布局了。
  • 高优先级的启动预加载方案。
    Application#onCreate() 阶段对布局进行预加载,到了 setContentView() 时候就直接使用预加载好的布局即可。
  • 随时预加载,不与具体的逻辑绑定,生命周期存货,可自定义清理生命周期。
    使用并发和字节码方式对其动态的生成

数据绑定

由于当下的 App 会有大量的网络请求,所以对网络请求数据的优化也是能带来很大收益的。

  • Gson 解析优化
    对于 Gson 的解析,我们每次使用已创建好的对象或者每次创建新的对象解析所带来的时间差异也是巨大的。
//with Cache
Gson gson = new Gson();
for(...){
    gson.from(...);
}
//without Cache
for(...){
    new Gson().from(...);
}
复制代码
  • 对于上述两种情况,其耗时如下,可见使用 Cache 带来的收益是很大的。
  • 1.webp.jpg
  • 数据协议优化:json -> protobuf
    protobuf 对于数据无论是压缩或者是不压缩的时候,由于其体积小使得传输时间远比 json 要小得多,其带来的收益是很大的。
  • 1.webp.jpg

View的渲染问题

对于 View 的渲染优化,我们可以有以下点

  • 移除不必要的背景图
  • 修改不合理的布局
  • 写高效的合理布局
  • 移除默认的 Window 布局
  • 绘制层级的优化

对于上述的这些渲染中出现的耗时点,我们可以使用将绘制、渲染放置于异步操作,交互放置于主线程中。对于这个问题,不同的公司有不同的解决方案。

  • Google
  • SurfaceView
    采用独立的线程进行绘制和渲染,自行控制生命周期。SurfaceView详解
  • jetpack Compose
    这是另一套 View 逻辑,用于替代现有的View。其使用组合优于继承的思想,重构出一套解耦的 UI 框架,这使得 View 更容易在异步进行绘制。
  • FaceBookLitho:在Android上构建高效UI的声明性框架。可以应用于复杂 UI 下进行高性能渲染。
  • 扁平化:其使用异步线程提前执行 measure 和 draw 方法,通过将布局系统与传统的Android View系统分离,Litho可以摆脱Android强加的UI线程限制。且 Litho 使用 Yoga 进行布局,并自动减少 UI 中包含的 ViewGroup 数(扁平化思想)。除了Litho的文本优化之外,这还允许更小的视图层次结构,并提高了内存和滚动性能。
    1.webp.jpg
  • 组件化:Litho 使用 Drawable 作为 Node 的绘制单元,实现了布局细粒度复用(使用Litho,每个UI项(如文本、图像或视频)都会单独回收。一旦一个项目离开屏幕,它就可以在UI中的任何地方重用,并与其他项目拼凑在一起,以创建新的UI元素。)和异步计算布局的能力。
  • 声明式 UI :需要重学,重构这套 UI 的编写,这也是其中的缺点。
  • 抖音
  • SurfaceView 和 TexureView 一起使用。前者是可以有单独层级,后者就是和 DecorView 一个层级。
    1.webp.jpg



相关文章
|
SQL Java API
深入探索Java的持久化技术——JPA(Java Persistence API)
【10月更文挑战第10天】深入探索Java的持久化技术——JPA(Java Persistence API)
849 0
|
监控 数据挖掘 BI
缺陷通知期限是什么?如何在项目中设定缺陷通知期限?
缺陷通知期限(DNP)是项目管理中,承包商完成工程或交付产品后,业主或客户有权通知承包商存在缺陷的特定时间段。此期限旨在保障项目质量、明确责任、合理分配风险及优化合同管理。在DNP内,承包商需对发现的缺陷进行修复。期限类型包括固定期限、分阶段期限和基于性能的期限。设定DNP需综合评估项目特性、行业惯例、风险因素,并通过协商确定,最终在合同中明确。
|
10月前
|
监控 算法 Java
深入理解JVM《G1垃圾收集器:面向局部收集与停顿模型的里程碑》
G1收集器是JDK 9+默认的高性能垃圾回收器,采用Region分区模型,实现可预测停顿时间。它通过RSet跟踪跨区引用,结合SATB算法确保并发标记准确性,兼顾低延迟与高吞吐,适用于大内存多核场景。
|
数据可视化 索引 Python
Python用Markowitz马克维兹有效边界构建最优投资组合可视化分析四只股票
Python用Markowitz马克维兹有效边界构建最优投资组合可视化分析四只股票
|
网络协议 数据库 网络架构
一张图带你精通 OSPF 8种邻居状态机!
【4月更文挑战第25天】
2770 0
一张图带你精通 OSPF 8种邻居状态机!
|
开发工具 git
git统计项目代码行数
git统计项目代码行数 显示项目的所有文件列表及行数
1998 0
|
安全 Android开发 iOS开发
深入探索Android与iOS的差异:从系统架构到用户体验
在当今的智能手机市场中,Android和iOS无疑是最受欢迎的两大操作系统。本文旨在探讨这两个平台之间的主要差异,包括它们的系统架构、开发环境、安全性、以及用户体验等方面。通过对比分析,我们可以更好地理解为何不同的用户群体可能会偏好其中一个平台,以及这些偏好背后的技术原因。
|
前端开发 JavaScript
vant NavBar 导航栏详解
vant NavBar 导航栏详解
1014 4