一、启动定义
启动:从手指点击app图标,到第一个页面加载完成.
二、启动类型在安卓中应用的启动方式分为以下几种:
1.冷启动冷启动:当启动应用时,后台没有该应用的进程,系统会创建一个新的进程分配给该应用。
冷启动会先创建和初始化 Application 类,再创建和初始化 MainActivity 类,最后显示在界面上。
2 .热启动热启动:当启动应用时,后台已有该应用的进程(如:按back键、home键)。
热启动只会创建和初始化 MainActivity 类,不会创建和初始化 Application,因为Application 只会初始化一次。
3 .首次启动首次启动:安装应用后第一次启动的过程。
首次启动也是冷启动,比起冷启动,还会做一些系统初始化工作,如缓存目录创建、数据库创建,所以首次启动花费的时间最长。首次启动的速度非常重要,毕竟影响用户对 App 的第一映像。
三、启动流程 1.创建流程- 点击应用图标后,进入Launcher的onClick(), 然后调用 startActivity (),然后调用 Instrumentation 的 execStartActivity()。
- Instrumentation 调用 ActivityManagerProxy (ActivityManagerService 在应用进程的一个代理对象) 的 startActivity ()。
- ActivityManagerProxy 跨进程调用 ActivityManagerService (运行在 system_server 进程)的 startActivity ()。
- ActivityManagerService 最后调用 zygoteSendArgsAndGetResult(), 通过 socket 发送给 zygote 进程,zygote 进程会孵化出新的应用进程。
- zygote 执行 ActivityThread 的 main()。在该方法里会先准备好 Looper 和消息队列,然后调用 attach 方法将应用进程绑定到 ActivityManagerService,然后进入 loop 循环,不断地读取消息队列里的消息,并分发消息。
- ActivityManagerService 保存应用进程的一个代理对象,然后 ActivityManagerService 通过代理对象通知应用进程创建入口 Activity 的实例,并执行它的生命周期函数。
创建应用进程之前的流程由系统决定,没办法优化。能够优化的是Application和MainActivity 的创建和初始化。
下面是 MainActivity 的启动流程:
通过命令行方式统计启动时间:
adb shell am start -W appplicationId/packageName.activityName
输出的结果类似于:
ThisTime
最后一个Activity的启动耗时;TotalTime
所有Activity(指定的Activity可能启动其他Activity)的启动耗时;。WaitTime
调用startActivity() 到最后一个Activity启动完成的时间,即当前Activity的onPause()时间+TotalTime
;
通过trace文件分析每个方法的花费时间.
1.生成trace文件
使用代码生成
先通过Debug类生成trace文件,注意加读写权限。
Debug.startMethodTracing("shixintrace");...Debug.stopMethodTracing();注意:在Applicaiton中开始trace,然后再MainActivity中结束trace,不会生成trace文件。
trace文件生成后存放在SD卡中,可能直接存放/sdcard,也可能存在外置专有目录中。
先通过以下命令找到具体路径:
adb shellcd /sdcardfind -name *.trace可能得到如下结果./Android/data/gsw.test1/files/shixintrace.trace然后退出shell状态,通过adb命令取出文件
adb pull sdcard/Android/data/gsw.test1/files/shixintrace.trace
使用 Android Studio生成
生成 trace 文件:Android Monitor -CPU监控-闹钟。
2.分析trace文件
如果使用代码生成trace文件,则需要用Android Studio打开.
分析trace文件:
- 先分析线程的执行时间,对时间较长的线程,再分析每个方法的执行时间和调用次数。
- 对于执行时间长的方法,需要分析每一步的执行时间,知道找到最深层的长耗时方法。
- 对于调用频繁的方法,需要逐步逐层分析调用和依赖。
- 在Application的构造器方法、attachBaseContext()、onCreate()方法中不要进行耗时操作的初始化,一些数据预取放在异步线程中,可以采取Callable实现。
- 对于sp(首选项)的初始化,因为sp的特性在初始化时候会对数据全部读出来存在内存中,所以这个初始化放在主线程中不合适,反而会延迟应用的启动速度,对于这个还是需要放在异步线程中处理。
- 对于MainActivity,由于在获取到第一帧前,需要对contentView进行测量布局绘制操作,尽量减少布局的层次,考虑StubView的延迟加载策略,当然在onCreate、onStart、onResume方法中避免做耗时操作。
设置特定的背景
通过设置theme的android:windowBackground属性实现。
如果设置的背景在应用启动完成后不再需要,可以再通过setTheme()设置背景。
不显示背景
通过设置theme的android:windowIsTranslucent属性实现:true代表透明;false代表非透明。
原文地址:https://blog.csdn.net/dshdhsd/article/details/79808172