在系统启动的时候,会启动PackageManagerService来安装系统的应用程序并解析AndroidMainfest.xml,从而获取组件信息。Launcher启动的时候会从PackageManagerService获取这个信息,存储在Intent变量里面用于传递。
通过Launcher#startActivitySafely传递给Activity#startActivity,进一步传递给Activity#startActivityForResult。Activity#startActivityForResult里会获取系统里面的ActivityThread实例内的数据类型为ApplicationThread的Binder本地对象和IBinder然后传递给Instrumentation#execStartActivity。
之后进入Instrumentation#execStartActivity,通过ServiceManager获取一个ActivityManagerService的代理对象并封装成ActivityManagerProxy,并进入ActivityManagerProxy#startActivity。在ActivityManagerProxy#startActivity内写入之前Intent传进来的参数后向ActivityManagerService发送一个START_ACTVITY_TRANSACTION的进程通信请求,这样step1-5就结束了。
接着就轮到由ActivityManagerService处理Launcher来发出的START_ACTVITY_TRANSACTION进程通信请求。
ActivityManagerService#startActivity内直接调用ActivityStack#startActivityMayWait,ActivityStack是用来描述Activity堆栈的。在ActivityStack内先通过PackageManagerService解析Intent的内容并存入ActivityInfo对象Info,后传入ActivityStack#startActivityLocked。
在ActivityStack#startActivityLocked内获取到源Activity、目标Activity的信息,PID,UID等信息一起传给ActivityStack#startActivityUncheckedLocked,ActivityStack#startActivityUncheckedLocked根据AndroidMainfest.xml内设定的launchMode来建立任务栈并启动Activity,就这样进入ActivityStack#resumeTopActivityLocked。
ActivityStack#resumeTopActivityLocked则给Launcher发送Paused状态的通知,方便MainActivity启动,后面的ActivityStack#startPausedLocked则为Launcer处理之前发送的Paused状态,等成功Paused后,在一定时间内由Launcer向ActivityManagerService发送一个启动MainActivity的通知,收到后由ApplicationThreadProxy#schedulePauseActivity通过其内部的Binder代理对象向Launcer发送SCHEDULE_PAUSE_ACITIVITY_TRANSACTION的进程通信请求。
接下来由Launcer来处理SCHEDULE_PAUSE_ACITIVITY_TRANSACTION的进程通信请求。
先进入 ApplicationThread#schedulePauseActivity,这个调用 ActivityThread#queueOrSendMessage来向Launcer主线程的消息队列发送PAUSE_ACTIVITY消息,在H#handleMessage内先将Message强制转换为IBinder(因为他是指向的一个Binder代理对象)接着调用 ActivityThread#handlePauseActivity函数,首先将Binder引用token转换成ActivityRecord的远程接口ActivityClientRecord,然后做了三个事情:
完成这三件事后Launcer的Paused请求就结束了。接着由ActivityManagerProxy#activityPaused通过内部的Binder代理对象给ActivityManagerService发送一个ACTIVITY_PAUSED_TRANSACTION的进程通信请求
接下来就有ActivityManagerService来处理Launcher发送的ACTIVITY_PAUSED_TRANSACTION进程通信请求 。
通过Binder机制就进入ActivityManagerService#activityPaused,但是呢又再次进入ActivityStack#activityPaused,由它来处理ACTIVITY_PAUSED_TRANSACTION的进程通信请求。做一系列的准备操作后执行ActivityStack#completePauseLocked,把mPausingActivity变量清空后调用ActivityStack#resumeTopActivityLokced进一步操作,它传入的参数即为代表Launcher这个Activity的ActivityRecord。这个函数取出堆栈顶端的Activity信息后就去调用ActivityStack#startSpecificActivityLocked。这个函数调用Process.start接口来创建一个新的进程,新的进程会导入android.app.ActivityThread类,并且执行它的main函数,这就是为什么我们前面说每一个应用程序都有一个ActivityThread实例来对应的原因。
接下来要分析新的应用程序进程启动过程。
新的应用程序进程启动的时候主要做了两件事情
在ActivityThread#main内的函数attach调用ActivityManagerService的远程接口ActivityManagerProxy#attachApplication函数,传入的参数是mAppThread,这是一个ApplicationThread类型的Binder对象,来传递ATTACH_APPLICATION_TRANSACTION的进程间通信请求。
接下来的是由在ActivityManagerService内处理新的应用程序进程所发出的ATTACH_APPLICATION_TRANSACTION的进程间通信请求,
ActivityManagerService#attachApplication直接将操作交给ActivityManagerService#attachApplicationLocked来锁定要启动的Acitivity是否为目标Activity,若是则启动ActivityStack#realStartActivityLocked。
这个函数先做一些准备工作,调用参数已经调整准确的thread变量的成员函数scheduleLaunchActivity,接着又Binder进入ApplicationThread#scheduleLaunchActivity并向ActivityManagerService发送类型为SCHEDULE_LAUCH_ACTIVITY_TRANSACTION的进程通信请求。
接下来就由ActivityManagerService来处理SCHEDULE_LAUCH_ACTIVITY_TRANSACTION的进程通信请求。
首先进入ApplicationThread#scheduleLaunchActivity,它将要启动的Activity信息封装成ActivityClientRecord对象并调用ActivityThread#queueOrSendMessage,将ActivityClientRecord封装成Message,并将它送入主线程消息队列。之后就进入H#handleMessage将Message转换成ActivityClientRecord对象,并将之存入到LoadApk对象中。在Activity内部就是用LoadApk来描述一个已经加载的Apk文件。最后调用ActivityThread#handleLaunchActivity来启动ActivityClientRecord描述的Activity对象。接着调用ActivityThread#performLaunchActivity来启动Activity并将Activity的状态变换为Resumed。ActivityThread#performLaunchActivity先收集要启动的Activity的相关信息,主要package和component信息,后创建Application对象和通过attach方法将上下文信息设置到MainActivity中去。最后调用MainActivity#onCreate。 这里不是直接调用MainActivity的onCreate函数,而是通过mInstrumentation的callActivityOnCreate函数来间接调用,前面我们说过,mInstrumentation在这里的作用是监控Activity与系统的交互操作,相当于是系统运行日志。
最后由MainActivity#onCreate来加载用户界面以及对用户界面上的控件进行初始化。这样根Activity就启动完成了
子Activity和根Activity的启动流程的基本上是一样的,只是启动的组件Action名称和ActivityRecord的信息换了一下,并且不用新建立应用程序进程
参考资料:
http://blog.csdn.net/luoshengyang/article/details/6689748
http://blog.csdn.net/luoshengyang/article/details/6703247