TotalTime: 242
WaitTime: 288
Complete
- ThisTime:是指调用过程中最后一个Activity启动时间到这个Activity的 startActivityAndWait调用结束;
- TotalTime:是指调用过程中第一个Activity的启动时间到最后一个Activity的 startActivityAndWait结束。
- WaitTime:是startActivityAndWait这个方法的调用耗时;
reportFullyDrawn
在某些特殊场景,我们可能不单单启动页的绘制完成回调时间就足够了,我们需要连启动页的闪屏广告接口数据成功回调之后才算一个完整的时间,这时我们可以使用reportFullyDrawn
public class WelcomeActivity extends MvpActivity implements WelcomeMvp.View {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_welcome);
// 请求数据
mvpPresenter.config();
}
@Override
public void finishRequest() {
// 数据回调
reportFullyDrawn();
}
}
PS:这个方式minSdkVersion需要API19+,所以要对SDK版本进行设置或判断。
####Traceview
Traceview是Android设备的一个非常好用的性能分析工具,它可以通过详细的界面,让我们跟踪程序的性能,并且能清晰地查看到每一个函数的耗时和调用次数。
####Systrace
Systrace非常直观地展示每个线程上面的API的调用顺序和耗时情况。
Traceview和Systrace都是DDMS面板的工具,但是现在AS3.0以上的版本不再建议使用了,所以这里就不详述,如果有兴趣的同学,可以看我上一篇文章《Android应用优化之流畅度实操》,里面有详细地说明这两个工具的用法。
####hugo
我们可以利用JakeWharton的hugo,通过注解的方式获取对应的类或者函数所消耗的时间。我们可以利用它对启动页Activity的生命周期来抠细节。
##启动优化实操
####用户体验优化
在冷启动优化的主要体验个人认为就是消除启动时的白屏/黑屏,因为白屏/黑屏对于用户使用的第一印象就是慢、卡顿。我们可以设置启动页的主题来达到目的。
windowDrawsSystemBarBackgrounds是对部分有系统操作栏的设置。接着是这个窗口背景色的布局;
启动页的广告展示完跳转到首页
,然后我们设置回我们的通用样式,可以在清单文件,也可以在代码中设置;
<activity
···
android:theme="@style/AppBaseFrameTheme"/>
通过对启动页的主题设置后,就会将白屏/黑屏抹去,用户点击App的图标就展示启动图,让用户先产生启动很快的“错觉”。同时这里可以通过动画,让启动页与首页之间的过渡更加自然。
##Application启动优化
从上图一的分析总结中,我对优化点Application的生命周期进行了加粗提示,接着我们回来对这部分进行优化实操。
Application#attachBaseContext()
Application启动会经过attachBaseContext()–>onCreate();这时大家从attachBaseContext的生命周期联想到什么?没错就是MultiDex分包机制。想必大家都会发现,自从我们方法数超出了65535处理了分包之后,启动白屏/黑屏的问题就出现了,分包机制是导致冷启动缓慢的重要原因,而现在部分应用采用插件化的方式来避免MultiDex带来的白屏问题,这虽然是一种方法,但是开发成本实在高,对于不少应用来说是不必要的。我们来聊一下MultiDex优化,首先MultiDex可分成运行时和编译时两个部分:
- 编译期:将App中的class以某种策略拆分在多个dex中,为了减少第一个dex也就主dex中包含的class数;
- 运行期: App启动时,虚拟机只加载主dex中的class。app启动以后,使用Multidex.install,通过反射机制修改ClassLoader中的dexElements来加载其他dex;
从网上的多篇实践分析中,他们主要采用的是异步方式。因为App起始会先加载主dex包,那么我们可以自主去处理分包的工作,我们将启动页和首页需要的库、组件等主要class分在主dex中,从而达到精分主dex包的大小,具体的操作写法,大家可以参考网上MultiDex启动优化文章,但是大家要注意在主dex的分包过程中,主dex经过我们一系列的优化操作减少了主dex的大小,因此也增大了NoClassDefFoundError的异常的可能,此时会导致我们的应用启动失败的风险,所以在优化后我们一定做好测试工作。
Application#onCreate()
经过attachBaseContext()后就到onCreate()生命周期,想必我们大部分的应用,会在这里对我们使用到的第三方库和组件进行初始化工作。由于版本不断迭代,第三方库的初始化都是直接写在onCreate()中,大量的初始化工作导致该生命周期过于沉重,我们应该对这些第三方库进行分类。下面是我整理我司App启动的工作分类:
看着上图,各种第三方工具初始化和业务逻辑初始化,影响启动时间。我们先对它们拆分成四部分。
(img-gAmPzQRw-1641964477305)]
看着上图,各种第三方工具初始化和业务逻辑初始化,影响启动时间。我们先对它们拆分成四部分。