启动优化
App启动是从点击打开App到首页启动起来的过程。冷启动消耗的时间最长,也是最有必要优化的。
Launcher通过Binder进程间通信机制通知ActivityManagerService,它要启动一个Activity。
ActivityManagerService通过Binder进程间通信机制通知Launcher进入Paused状态。
Launcher通过Binder进程间通信机制通知ActivityManagerService,它已经准备就绪进入Paused状态, 于是ActivityManagerServicey利用Zygote.fork()创建一个新的进程,用来启动一个ActivityThread实例, 即将要启动的Activity就是在这个ActivityThread实例中运行。
ActivityThread通过Binder进程间通信机制将一个ApplicationThread类型的Binder对象传递给ActivityManagerService,以便以后ActivityManagerService能够通过这个Binder对象和它进行通信。
ActivityManagerService通过Binder进程间通信机制通知ActivityThread,现在一切准备就绪,它可以真正执行Activity的启动操作了。
ActivityThread.main()
调用Looper.prepareMainLooper()创建当前线程的Looper,并且作为当前App主要的Looper。
创建ActivityThread,ActivityThread使用调用attachApplication()方法使用Binder机制向AMS传递了一个Application对象,AMS的接受到后调用相应的attachApplication()方法
attachApplication()调用attachApplicationLocked(), attachApplicationLocked()借助Binder通信IApplicationThread调用ApplicationThread.bindApplication(),其中sendMessage(H.BIND_APPLICATION, data),然后在ActivityThread.H出接收消息,调用handleBindApplication(), LoadedApk.makeApplication()创建了Application实例,而后mInstrumentation.callApplicationOnCreate(app),调用了Application.onCreate()
public void callApplicationOnCreate(Application app) {
app.onCreate();
}
AMS得到了ActivityThread的Application对象后,又个给ActivityThread发送了一个消息,调用了ApplicationThread的performLaunchActivity()方法,performLaunchActivity() 借助Instrumentation,完成Activity创建,启动等流程。
创建Context:createBaseContextForActivity
Instrumentation.newActivity
Instrumentation.callActivityOnCreate
public void callActivityOnCreate(Activity activity, Bundle icicle) {
prePerformCreate(activity);
//activity.performCreate调用了activity.onCreate,执行了生命周期方法
activity.performCreate(icicle);
postPerformCreate(activity);
}
默认Activity Theme设置为如下属性,windowBackground设置启动图,在Activity.onCreate中,setContentView之前,调用setTheme(),设置Theme为Activity可见之后的Theme。
ContentProvider.onCreate():在Application的启动流程中,会依次执行attachBaseContext,ContentProvider的onCreate,Application的onCreate方法。
所以ContentProvider的onCreate方法中,一定不能有耗时操作
Application.onCreate()优化:第三方库等初始化,在不影响后续功能的情况下进行异步加载。
adb shell am start-W [包名/activity名] 该命令具体实现在/frameworks/base/cmds/am/srcl/com/android/commands/am/Am.java,原理是跨Binderi调用 ActivityManagerService.startActivityAndWait()接口,其中返▣数据分别调用对应:
ThisTime:该activity启动耗时 TotalTime:应用自身启动耗时=ThisTime+应用application等资源启动时间 VaitTime:系统启动应用耗时=TotalTime+系统资源启动时间