根Activity和子Acitivity的启动过程分析

1.Activity的启动过程

1.1 根Activity

  1. Launcher组件向ActivityManagerService发送一个启动MainActivity的进程通信请求。
  2. ActivityManagerService首先将要启动的MainActivity的信息保存下来,然后再像Launcher组件发送一个进入中止状态的进程通信请求。
  3. Launcher进入到中止状态后就会像ActivityManagerService发送一个已进入中止状态的进程通信请求,以便ActivityManagerService可以继续执行启动MainActivity组件的操作。
  4. ActivityManagerService发现用来运行MainActivity的应用程序进程不存在,就会先启动一个新的应用程序进程。
  5. 新的应用程序进程启动完成后,就会像ActivityManagerService发送一个启动完成的进程通信请求,以便ActivityManagerService可以继续执行启动MainActivity的操作。
  6. ActivityManagerService将第2步保存下来的MainActivity信息发送给第4步创建的应用程序进程,以便它可以将MainActivity启动起来

根Activity和子Acitivity的启动过程分析_第1张图片

1.2 子Activity

  1. MainActivity组件向ActivityManagerService发送一个启动SubMainActivity的进程通信请求。
  2. ActivityManagerService首先将要启动的SubMainActivity的信息保存下来,然后再向MainActivity组件发送一个进入中止状态的进程通信请求。
  3. MainActivity进入到中止状态后就会像ActivityManagerService发送一个已进入中止状态的进程通信请求,以便ActivityManagerService可以继续执行启动SubMainActivity组件的操作。
  4. ActivityManagerService发现用来运行SubMainActivity的应用程序进程已经存在,就会将SubMainActivity的信息发送给应用程序进程,以便它可以将SubMainActivityInProcess组件启动起来

2.根Activity启动的源码分析

根Activity和子Acitivity的启动过程分析_第2张图片

在系统启动的时候,会启动PackageManagerService来安装系统的应用程序并解析AndroidMainfest.xml,从而获取组件信息。Launcher启动的时候会从PackageManagerService获取这个信息,存储在Intent变量里面用于传递。

通过Launcher#startActivitySafely传递给Activity#startActivity,进一步传递给Activity#startActivityForResult。Activity#startActivityForResult里会获取系统里面的ActivityThread实例内的数据类型为ApplicationThread的Binder本地对象和IBinder然后传递给Instrumentation#execStartActivity。

  • ActivityThread:描述一个应用程序进程(系统每启动一个进程就会加载一个ActivityThread实例),传递其内部的数据类型为ApplicationThread的Binder本地对象可以与ActivityManagerService进行通信,这样就可以传递中止(Paused)状态了
  • IBinder:这个是Binder的代理对象,并指向了ActivityManagerService内部的ActivityRecord,ActivityRecord内部记录了Activity的运行状态和信息,利于维护。这样ActivityManagerService就可以获取Launcher更详细的信息了。

之后进入Instrumentation#execStartActivity,通过ServiceManager获取一个ActivityManagerService的代理对象并封装成ActivityManagerProxy,并进入ActivityManagerProxy#startActivity。在ActivityManagerProxy#startActivity内写入之前Intent传进来的参数后向ActivityManagerService发送一个START_ACTVITY_TRANSACTION的进程通信请求,这样step1-5就结束了。

接着就轮到由ActivityManagerService处理Launcher来发出的START_ACTVITY_TRANSACTION进程通信请求。

根Activity和子Acitivity的启动过程分析_第3张图片
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的进程通信请求。

根Activity和子Acitivity的启动过程分析_第4张图片
先进入 ApplicationThread#schedulePauseActivity,这个调用 ActivityThread#queueOrSendMessage来向Launcer主线程的消息队列发送PAUSE_ACTIVITY消息,在H#handleMessage内先将Message强制转换为IBinder(因为他是指向的一个Binder代理对象)接着调用 ActivityThread#handlePauseActivity函数,首先将Binder引用token转换成ActivityRecord的远程接口ActivityClientRecord,然后做了三个事情:

  1. 如果userLeaving为true,则通过调用performUserLeavingActivity函数来调用Activity.onUserLeaveHint通知Activity,用户要离开它了;
  2. 调用performPauseActivity函数来调用Activity.onPause函数,我们知道,在Activity的生命周期中,当它要让位于其它的Activity时,系统就会调用它的onPause函数;
  3. 它通知ActivityManagerService,这个Activity已经进入Paused状态了,ActivityManagerService现在可以完成未竟的事情,即启动MainActivity了。

完成这三件事后Launcer的Paused请求就结束了。接着由ActivityManagerProxy#activityPaused通过内部的Binder代理对象给ActivityManagerService发送一个ACTIVITY_PAUSED_TRANSACTION的进程通信请求

接下来就有ActivityManagerService来处理Launcher发送的ACTIVITY_PAUSED_TRANSACTION进程通信请求 。
根Activity和子Acitivity的启动过程分析_第5张图片

通过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实例来对应的原因。

接下来要分析新的应用程序进程启动过程。

根Activity和子Acitivity的启动过程分析_第6张图片

新的应用程序进程启动的时候主要做了两件事情

  • 在进程中创建一个ActivityThread对象,并且调用attach想ActivityManagerService发送一个启动完成的通知
  • 调用Looper类的静态成员函数prepareMainLooper创建一个消息循环,并且在向ActivityManagerService发送启动完成通知之后,使得当前进程进入到这个消息循环中。

在ActivityThread#main内的函数attach调用ActivityManagerService的远程接口ActivityManagerProxy#attachApplication函数,传入的参数是mAppThread,这是一个ApplicationThread类型的Binder对象,来传递ATTACH_APPLICATION_TRANSACTION的进程间通信请求。

接下来的是由在ActivityManagerService内处理新的应用程序进程所发出的ATTACH_APPLICATION_TRANSACTION的进程间通信请求,

根Activity和子Acitivity的启动过程分析_第7张图片

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就启动完成了

3.子Activity启动的源码分析

子Activity和根Activity的启动流程的基本上是一样的,只是启动的组件Action名称和ActivityRecord的信息换了一下,并且不用新建立应用程序进程

根Activity和子Acitivity的启动过程分析_第8张图片

根Activity和子Acitivity的启动过程分析_第9张图片

根Activity和子Acitivity的启动过程分析_第10张图片
根Activity和子Acitivity的启动过程分析_第11张图片

参考资料:
http://blog.csdn.net/luoshengyang/article/details/6689748
http://blog.csdn.net/luoshengyang/article/details/6703247

你可能感兴趣的:(根Activity和子Acitivity的启动过程分析)