Android App 的启动过程简析

时间:2022-11-13 04:18:47
首先,在APK文件安装的时候,PackageManager会解析APK中重要的AndroidManifest.xml文件,你在AndroidManifest.xml中注册过的所有Activity和Service等四大组件的信息,也就会在此刻被PM获取到并存储起来。
当你在安装完APK文件并打开该app的时候,这里分两种情况。第一是你在LAUNCH中点击app的图标打开,第二是在安装完成界面直接打开,这两种情况打开的本质相同。
第一种情况下,在你点击app的图标后,LAUNCH会通过shortcutinfo中存储的intent调用startActivity方法来启动这个app的默认Activity,在LAUNCH调用startActivity方法后,调用流程会转到Instrumentation对象的execStartActivity方法里,在此处会远程调用AMS的startActivity方法。
在start这个Activity之前,AMS首先必须要获得启动的activity信息,这个信息会通过调用 startActivityMayWait方法以及传进来的intent并结合PM的resolveIntent方法返回,要启动的activity信息获取完成后,需要将这个activityinfo保存到Intent中。然后在通过AMS的startActivityLocked方法来new一个和该Activity相匹配的ActivityRecord对象,AMS正是通过操控ActivityRecord对象(当然还包括TaskRecord以及ProcessRecord)来管理Activity的,然后AMS会进行一系列task以及Activity是否复用的判断,如果没有可复用的activity,那么需要启动一个新的activity,如果有可复用的activity,那么activity的启动过程至此结束,直接调用resumeTopActivityLocked方法即可。
等上述过程完成后,接着AMS会调用startProcessLocked方法来通知Zygote孵化并启动新进程,然后会开启该app的主线程,此刻,调用流程进入ActivityThread类中。

ActivityThread类从main方法开始执行,内部调用prepareMainLooper方法创建消息队列,然后new一个ActivityThread对象,在初始化方法里创建一个H类对象和ApplicationThread对象,ApplicationThread对象来响应AMS的远程调用,然后ActivityThread对象会调用attach方法,内部会远程调用AMS的attachApplication方法,接着调用realstartActivityLocked方法来通过远程调用通知Activity可以创建了,ActivityThread里面的ApplicationThread对象会响应这个通知,并调用scheduleLaunchActivity方法完成Activity调用前的信息初始化工作,然后通过H类把activityStart的通知发送到消息队列中,主线程会异步的从消息队列中取这个消息并调用performLaunchActivity方法来启动activity,启动的过程本身其实并不复杂,只是在启动之前会进行一系列相关信息的初始化,然后会使用Classloader类加载器加载对应的activity类,然后newInstance对应activity类的实例,然后是context,title,config等信息的获取,之后调用attach方法把之前获取和设置的东西和当前的activity类绑定,这也就是activity类之后能运行起来要依赖的东西,绑定结束之后,activity实例调用setTheme方法给自己设置主题,然后通过调用Instrumentation对象的callActivityOnCreate方法来调起这个默认activity的onCreate方法,接下来就是onStart生命周期方法的调用(需要结合ActivityRecord中activity的状态),这里依然会通过AMS,ActivityThread,Instrumentation三者的相互合作来完成。至此app就启动起来了。