上一篇App启动已经初步的分析了有哪些启动类型以及怎么去简单的测量App启动的耗时,这一篇主要使用两个工具来粗略的分析启动的耗时到底在哪些地方。下面开始介绍
1 使用systrace抓取trace.html文件
在使用Systrace之前,建议大家好好参考官方的这边介绍systrace官方介绍这里面详细的介绍了systrace抓取trace.html的命令以及选项的意思,我采用的命令如下
call python D:\Android\sdk\platform-tools\systrace\systrace.py -t 5 -a com.qiyei.mall sched gfx input view wm am app
执行命令后,再点击App启动,最后会在当前目录下生成trace.html文件
2 systrace分析启动耗时
用chrome打开trace.html文件,找到自己的进程com.qiyei.mall
可以看到会有不同的TraceTAG,例如bindApplication,ActivityStart等,我们来依次查看以下几个
Wall Duration : 代码持续耗时时间,即这段代码的耗时时间
CPU Duration : 这段代码在CPU上真正的耗时
可以看到ActivityThreadMain中CPU Duration与Wall Duration相差不大,但是bindApplication中CPU Duration与Wall Duration相差两倍,因此我们知道在bindApplication过程中耗时较长,可以进行优化。
依次查看其它过程,特别是绘制第一帧
可以看到已经给我们了警告,我们的第一次测量花费了121.94ms,第二次为23.05ms,布局花了17.85ms
因此,综合systrace来看,我们的启动过程中耗时的主要地方在bindApplication和绘制第一帧过程中
3 使用TraceView抓取xxx.trace文件
在Application中添加如下代码开始抓取TraceView
Debug.startMethodTracing("mall_start");
在HomeActivity中onWindowFocusChanged记录结束点
override fun onWindowFocusChanged(hasFocus: Boolean) {
super.onWindowFocusChanged(hasFocus)
Debug.stopMethodTracing()
}
4 TraceView分析启动耗时
在使用TraceView之前,阅读使用TraceView检查Trace log和使用 CPU Profiler 检查 CPU Activity 和函数跟踪。
在AS中导入生成的mall_start.trace文件,如下图
可以看到,SDKManager.initSDK(),ARouter.init(),JPushInterface.init()分别位列耗时的三大元凶,其中又以ARouter.init()耗时最多,因此我们就可以针对性的优化
5 APP启动白屏/黑屏问题
白屏或黑屏,具体是哪一个,取决于app的Theme使用的是dark还是light主题,对于冷启动来说点击你app那一刻到系统调用Activity.onCreate()之间的时间段。在这个时间段内,WindowManager会先加载app主题样式中的windowBackground作为app的预览元素,然后再真正去加载activity的layout布局。因此在未加载前的界面就有app主题样式中的windowBackground决定。
因此解决办法如下:
新建一个启动页的theme
<style name="SplashTheme" parent="AppTheme">
<!-- Customize your theme here. -->
<item name="android:windowFullscreen">true</item>
<item name="android:windowBackground">@drawable/app_startup</item>
</style>
在manifest.xml中应用这个主题
<activity android:name=".ui.activity.MainActivity"
android:theme="@style/SplashTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
然后在首屏Activity中在setContent之前使用原来主题
override fun onCreate(savedInstanceState: Bundle?) {
setTheme(R.style.AppTheme)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
….
}
这样启动白屏,黑屏的问题就解决了