Android 启动优化方案

一、前言

在开始启动的优化之前,需要明确启动的启动耗时的指标计算规则,在这里我们定义的规则如下:

启动耗时 = HomeActivity.onWindowFoucusChange - Application.onCreate

首页的首帧渲染的时间,减去 Application onCreate 回调的时间,即为应用启动耗时的时间。

二、Application 阶段方案

在 Application 中的耗时是启动优化的大头,各种组件以及业务线在 Application 完成初始化的逻辑。因此,优化的一个整体思路是,组件异步初始化、业务线懒加载等。

1、组件异步初始化

优化启动耗时的本质上是优化主线程的耗时,因此可以把一些耗时的组件进行异步初始化。

2、延迟业务线初始化时机

在之前的启动框架中,如何完成对业务线的初始化呢?方案其实很简单:提供一个接口层,定义一个 ApplicationDelegate 的类,在该类中包含了 Application 的各个方法的回调时机,各个业务线只需要实现这个接口就行。主端在 Application 中通过 SPI 的方式获取到各个业务线的接口实现,从而完成业务线的初始化。

现在需要怎么做呢?既然是延迟业务线的初始化时机,那么就不应该在应用启动的时候完成业务初始化。应该把这个初始化的时机,交给业务自己,由业务自己完成业务逻辑的初始化。

3、ContentProvider 的优化

ContentProvider 是 Android 的四大组件之一,只有它是在 Android 应用启动的时候完成初始化的。在 Application attachContext 的回调之后,系统会循环遍历所有注册的 ContentProvider,并完成初始化。

ContentProvider 相对来说是一个比较重量级的组件,一个空的 ContentProvider,执行的耗时就达到了 2ms 左右。

但是得益于能够在 Application 的时候就完成初始化,业务大多都喜欢搞一个自己 ContentProvider,便于完成自己业务初始化以及获取 Application Context。

针对的 ContentProvider 的优化措施是,缩减 ContentProvider 的数量。如何缩减呢:

  1. 删除无用的 ContentProvider
  2. 合并 ContentProvider
  3. ContentProvider 的耗时操作延迟处理

3、组件初始化依赖

组件异步初始化之后,但是某些个组件的存在依赖关系,即 A 组件的初始化,需要 B 组件先完成初始化,该如何做呢?

我们可以使用 Android 官方提供的 StartUp 库,里面提供了组件的依赖关系。

4、组件初始化回滚机制

在初始进行异步之后,可能会有考虑不到的点,从而导致线上问题的发生。为了最大程度避免线上问题的发生,减少损失,可以通过开关进行控制。

控制的粒度可精确到某个组件,从而避免影响到整个启动需求的上线。

三、Activity 阶段方案

1、Splash 耗时优化

这一块的优化可以从两个方面来讲:

一方面,合并 Splash 页面和 Home 页面,降低 Activity 切换的耗时。

另一方面,缓存 Splash 接口,并行预加载首页的接口。

在我们进入首页之前,我们会在 Splash 页面先请求一个接口,只有在接口请求完成之后,才会进入首页,完成首页接口请求已经页面展示。

如果接口请求失败,则会卡在 Splash 页面。因果埋点数据发现,大部分情况下,用户在 Splash 的接口返回的数据都是相同的,于是在这里我们可以缓存 Splash 的接口。

另外,如果 Splash 接口没有缓存,我们还有并行请求首页的接口。这样才进入首页之后,拿到数据就可以直接渲染首页的页面了。

2、View 层级优化

减少 View 的嵌套层级,Android 在解析 XML 的时候创建 View 的时候,是通过反射以及递归实现的,嵌套的层级越深,渲染所消耗的时间就越多。

还有一种方案,通过 X2C 的方式,在编译期间把 XML 转化成代码,能减少解析的耗时。但是这种方案可能存在一定的风险,故我们没有采用。

五、防劣化方案

对于防劣化的方案,我们在线上打一些埋点,然后基于埋点,建立线上的看板,并创建监控报表。

相关推荐
柚鸥ASO优化1 小时前
安卓APP推广的“降本增效”密码:守好商店内,打好商店外
android·aso优化
我是一颗柠檬1 小时前
【Java项目技术亮点】EXPLAIN深度分析与慢查询治理
android·java·开发语言
Android-Flutter1 小时前
android compose shadow 阴影 使用
android·kotlin·compose
帅次2 小时前
Android 高级工程师面试:Java 多线程与并发 近1年高频追问 22 题
android·java·面试
2501_943782352 小时前
【共创季稿事节】摩斯电码转换器:编码表与双向转换的实现
android·华为·鸿蒙·鸿蒙系统
STCNXPARM2 小时前
Android selinux详解
android·selinux
jzwalliser2 小时前
安卓手机玩转Manim动画制作
android·manim
zhangphil3 小时前
Android图片解码器libjpeg-turbo vs Skia最佳实践
android
河铃旅鹿3 小时前
在Ubuntu系统上为Android交叉编译OpenSSL
android·linux·ubuntu
nannan85863 小时前
android 性能+AI 日志库-StatLog
android