startActivity分为两种,一种是从根Activity即Launcher组件启动,一种是子Activity启动。我们这里分析从Launcher启动新MainActivity的过程。
Launcher组件在它自己的进程中,用户在Home界面点击某个应用程序快捷图标时会触发父类Activity的startActivity方法,实质上归根结底是调用了Activity的startActivityForResult这个方法,我们在项目中也会用到。然后会继续调用Instrumentation的execStartActivity方法。Instrumentation用来监视应用程序和系统之间的交互,此例中,通过Instrumentation获取到系统服务AMS的代理,以便通知系统Launcher所在进程的应用程序需要开启一个新的Activity。以上都在Launcher所在的进程,下面就该进入到了AMS所在的进程中了。
Launcher通过代理将IApplicationThread 和 token (一个IBinder对象)给到了AMS,这里的IApplicationThread代表Launcher所在的应用程序进程,AMS需要知道在跟哪个应用程序进行交互;token指向了在AMS已保存的一个ActivityRecord对象,当Launcher启动后,AMS会将显示应用程序快捷图标的(Home)界面通过ActivityRecord保存起来,并且设置一个token指向它,通过token就能拿到此界面的所有信息。AMS收到请求后也会执行一个startActivity方法,然后将携带的参数给到ActivityStarter的startActivityMayWait方法中,在这个方法中首先通过IApplicationThread拿到了保存在AMS中的一个ProcessRecord对象,uid、pid等信息都保存在ProcessRecord中,其次通过token找到了一个ActivityRecord对象,这里有Home界面的信息,最后创建了一个新的ActivityRecord对象,代表将要启动的那个Activity,至此一个进程和两个Activity 在AMS对应的三个对象(一个ProcessRecord两个ActivityRecord)都有了 。然后调用ActivityStarter的startActivityUnchecked方法,ActivityStarter设置了将要启动Activity的intent和flag属性,并且将参数信息交给了ActivityStackSupervisor,接连调用ActivityStackSupervisor和ActivityStack的resumeTopActivity方法,把MainActivity放到栈顶,欲将正在激活状态的Launcher组件设置为Pause,因此接下来AMS向Launcher所在的进程发送IPC,告诉它将自己设置为Pause状态,调用方法为schedulePauseActivity。在Launcher进程的ActivityThread的对象中保有一个ApplicationThread对象,该对象就是处理AMS发送过来的IPC。沿着代码最终该消息被类型为Handler的H所处理,调用handlePauseActivity方法。该方法主要有三方面作用:第一发送一个用户离开事件的通知;第二告诉Instrumentation,让相应Activity进入Pause状态,执行onPause方法;第三完成一些数据的读写操作,为了以后恢复数据能保持原样。Launcher进程完成它的Pause任务后会继续给AMS发送消息告诉它已完成任务。于是在AMS的activityPaused的方法中得知结果,remove掉message,将MainActivity启动起来。这里会判断MainActivity的所在的应用程序进程是否存在,如果存在直接启动,如果不存在需要新建一个进程再开启Activity。AMS调用ActiivtyThread.main方法,该方法是启动一个新进程的入口。新进程启动有两个重要的事情,第一是初始化一个ActivityThread对象,利用attach方法向AMS发送启动完成的通知;第二是在新进程中创建消息循环,并使进程进入到循环中。AMS收到新进程发来的通知,这里面包含一个ApplicationThread对象,这个对象是Binder类型,作用是将新进程与AMS之间联系起来,使得他们可以进行通信。这个ApplicationThread对象是在ActivityThread初始化的时候创建的。AMS通过参数PID拿到之前就已经为该新进程创建的一个ProcessRecord对象app,对app进行初始化,将自己内部的thread成员变量指向参数ApplicationThread的代理对象。至此,AMS就可以与新进程进行通信。
通过调用AMS内部的ActivityStackSupervisor对象attachApplication的方法,将正要启动的MainActivity和它所在的进程的信息保存在ActivityRecord、ProcessRecord等类中,然后调用realStartActivityLocked方法,通知新进程准备加载MainActivity。
新进程收到AMS发来的启动Activity的命令之后,将Activity信息保存到ActivityClientRecord中,向本进程的主线程(即ActivityThread)发送一个message。在ActivityThread内部的成员变量H(即一个Handler)接收到message,在LAUNCH_ACTIVITY中进行处理。首先得到一个LoadedApk对象(Android应用程序都会最终打包成一个apk文件,apk里面保存了所有的资源文件,LoadedApk相当于描述了一个Apk文件),它里面封装了所有关于该应用程序的资源文件。当一个进程启动应用程序时,要把它的资源文件加载进来。这里将LoadedApk保存到了ActivityClientRecord的成员变量中。
最终启动MainActivity分为三小步:
a将上述封装好的ActivityClientRecord作为参数交给performLaunchActivity方法。对象Instrumentation是管理应用Application、Activity组件,Service组件等生命周期的,因此performLaunchActivity方法首先通过mInstrumentation.newActivity创建一个activity的实例。
b然后初始化一个Application对象:利用LoadedApk的makeApplication方法去构建一个Application实例。这里先创建一个ContextImpl对象,该对象是对应Application生成的上下文环境,Context,然后通过Application的attach方法将Context和LoadedApk保存在Application对象中。最后instrumentation.callApplicationOnCreate(app);去执行了Application的onCreate方法。
c创建一个对应Activity的ContextImpl对象,利用Activity的attach方法完成一些配置设定(例如保存自己的context,初始化PhoneWindow对象等),最后mInstrumentation.callActivityOnCreate调用Activity的onCreate方法完成整个启动过程。
Launcher组件在它自己的进程中,用户在Home界面点击某个应用程序快捷图标时会触发父类Activity的startActivity方法,实质上归根结底是调用了Activity的startActivityForResult这个方法,我们在项目中也会用到。然后会继续调用Instrumentation的execStartActivity方法。Instrumentation用来监视应用程序和系统之间的交互,此例中,通过Instrumentation获取到系统服务AMS的代理,以便通知系统Launcher所在进程的应用程序需要开启一个新的Activity。以上都在Launcher所在的进程,下面就该进入到了AMS所在的进程中了。
Launcher通过代理将IApplicationThread 和 token (一个IBinder对象)给到了AMS,这里的IApplicationThread代表Launcher所在的应用程序进程,AMS需要知道在跟哪个应用程序进行交互;token指向了在AMS已保存的一个ActivityRecord对象,当Launcher启动后,AMS会将显示应用程序快捷图标的(Home)界面通过ActivityRecord保存起来,并且设置一个token指向它,通过token就能拿到此界面的所有信息。AMS收到请求后也会执行一个startActivity方法,然后将携带的参数给到ActivityStarter的startActivityMayWait方法中,在这个方法中首先通过IApplicationThread拿到了保存在AMS中的一个ProcessRecord对象,uid、pid等信息都保存在ProcessRecord中,其次通过token找到了一个ActivityRecord对象,这里有Home界面的信息,最后创建了一个新的ActivityRecord对象,代表将要启动的那个Activity,至此一个进程和两个Activity 在AMS对应的三个对象(一个ProcessRecord两个ActivityRecord)都有了 。然后调用ActivityStarter的startActivityUnchecked方法,ActivityStarter设置了将要启动Activity的intent和flag属性,并且将参数信息交给了ActivityStackSupervisor,接连调用ActivityStackSupervisor和ActivityStack的resumeTopActivity方法,把MainActivity放到栈顶,欲将正在激活状态的Launcher组件设置为Pause,因此接下来AMS向Launcher所在的进程发送IPC,告诉它将自己设置为Pause状态,调用方法为schedulePauseActivity。在Launcher进程的ActivityThread的对象中保有一个ApplicationThread对象,该对象就是处理AMS发送过来的IPC。沿着代码最终该消息被类型为Handler的H所处理,调用handlePauseActivity方法。该方法主要有三方面作用:第一发送一个用户离开事件的通知;第二告诉Instrumentation,让相应Activity进入Pause状态,执行onPause方法;第三完成一些数据的读写操作,为了以后恢复数据能保持原样。Launcher进程完成它的Pause任务后会继续给AMS发送消息告诉它已完成任务。于是在AMS的activityPaused的方法中得知结果,remove掉message,将MainActivity启动起来。这里会判断MainActivity的所在的应用程序进程是否存在,如果存在直接启动,如果不存在需要新建一个进程再开启Activity。AMS调用ActiivtyThread.main方法,该方法是启动一个新进程的入口。新进程启动有两个重要的事情,第一是初始化一个ActivityThread对象,利用attach方法向AMS发送启动完成的通知;第二是在新进程中创建消息循环,并使进程进入到循环中。AMS收到新进程发来的通知,这里面包含一个ApplicationThread对象,这个对象是Binder类型,作用是将新进程与AMS之间联系起来,使得他们可以进行通信。这个ApplicationThread对象是在ActivityThread初始化的时候创建的。AMS通过参数PID拿到之前就已经为该新进程创建的一个ProcessRecord对象app,对app进行初始化,将自己内部的thread成员变量指向参数ApplicationThread的代理对象。至此,AMS就可以与新进程进行通信。
通过调用AMS内部的ActivityStackSupervisor对象attachApplication的方法,将正要启动的MainActivity和它所在的进程的信息保存在ActivityRecord、ProcessRecord等类中,然后调用realStartActivityLocked方法,通知新进程准备加载MainActivity。
新进程收到AMS发来的启动Activity的命令之后,将Activity信息保存到ActivityClientRecord中,向本进程的主线程(即ActivityThread)发送一个message。在ActivityThread内部的成员变量H(即一个Handler)接收到message,在LAUNCH_ACTIVITY中进行处理。首先得到一个LoadedApk对象(Android应用程序都会最终打包成一个apk文件,apk里面保存了所有的资源文件,LoadedApk相当于描述了一个Apk文件),它里面封装了所有关于该应用程序的资源文件。当一个进程启动应用程序时,要把它的资源文件加载进来。这里将LoadedApk保存到了ActivityClientRecord的成员变量中。
最终启动MainActivity分为三小步:
a将上述封装好的ActivityClientRecord作为参数交给performLaunchActivity方法。对象Instrumentation是管理应用Application、Activity组件,Service组件等生命周期的,因此performLaunchActivity方法首先通过mInstrumentation.newActivity创建一个activity的实例。
b然后初始化一个Application对象:利用LoadedApk的makeApplication方法去构建一个Application实例。这里先创建一个ContextImpl对象,该对象是对应Application生成的上下文环境,Context,然后通过Application的attach方法将Context和LoadedApk保存在Application对象中。最后instrumentation.callApplicationOnCreate(app);去执行了Application的onCreate方法。
c创建一个对应Activity的ContextImpl对象,利用Activity的attach方法完成一些配置设定(例如保存自己的context,初始化PhoneWindow对象等),最后mInstrumentation.callActivityOnCreate调用Activity的onCreate方法完成整个启动过程。