APP 优化 - activity 启动优化
activity 的优化算是一个重点吧,activity 的启动本来就是挺耗时的,我们需要优化的是那种启动极其耗时的,比如启动新 activity ,会让用户看 1秒多的黑屏,这就不好的了,可能不是所有的朋友的会碰到这个问题,产生这样的 activity 原因时多种多样的,根本原因则是:
- 上个页面的 handle 任务没有销毁
- activity 启动中有大量非系统耗时任务
- activity xml 布局非常复杂,渲染界面很耗时
不管大家写的怎么样,基本就是这几个原因会造成 activity 启动慢
我们先来看看一个经典的图,activity 和 view 的渲染过程

新界面启动,先执行 activity 3个初始化生命周期函数,执行完之后才会对界面元素 view 执行测量,绘制,渲染,这时我们才能看到实际界面内容,然后还会执行 activity 启动动画
上面的任何任务卡顿都会造成,我们延迟看到页面
解决思路
1. handle 问题
对于handle 问题,我们可以用 StallBuster 工具查看页面启动时 handle 系统任务栈的情况,比如下图就是 handle 任务没有清空,影响下个页面启动

所以我们在页面关闭或是不显示时,该关的一定要关
2. xml 布局效率
xml 布局层级一定要精简,要不真的非常耗时的,我碰到过自己写的 xml 耗时 1秒多的 ~
这里我们可以用 Hierarchy Viewer 工具 查看 xml 布局效率,用 ConstraintLayout 约束布局 来减少xml 层级,遵照Android UI性能优化实战 的思路,去掉不必需要的背景,减少过度绘制
3. 延迟操作
activity 的 oncreate 我们一箱习惯写各种初始化操作的,但是很多时候这里面就有耗时操作,所有我们可以 activity 页面渲染完毕再去做这些初始化操作及其后面的获取数据的操作
activity 的延迟操作有2个思路:
private Handler myHandler = new Handler();
private Runnable mLoadingRunnable = new Runnable() {
@Override
public void run() {
updateText(); //更新UI线程
}
};
getWindow().getDecorView().post(new Runnable() {
@Override
public void run() {
myHandler.post(mLoadingRunnable);
}
});
这2种写法有区别吗,有,而且很大。系统 UI 线程的所有操作都是通过在 handle 里面添加任务执行的,当我们在谁的初始化时添加 handle 任务,就是表示在谁的渲染之后执行
- 写法1 表示在 activity 的初始化完成后执行任务,也就是 onresume 之后执行
- 写法1 表示在 view 控件的初始化完成后执行任务,也就是 view 显示之后执行
大家可以看 trace 图


可以明显的看到写法1 的 handle 任务是在 rootviewimpl 渲染 view 之前执行的