Activity类的成员变量mMainThread的类型为ActivityThread,用来描述一个应用程序进程。系统每当启动一个应用程序进程时,都会在它里面加载一个ActivityThread实例,并且会将这个ActivityThread类实例保存在每一个在该进程中启动的Activity组件的父类Activity的成员变量mMainThread中。(该进程中每一个启动的Activity都会保存一个ActivityThread实例)
ActivityThread类的成员函数getApplicationThread()用来获取它内部的一个类型为ApplicationThread的BInder本地对象。
将Luncher组件所运行在的应用程序进程的ApplicationThread对象作为参数传递给成员变量mInstrumentation的成员函数execStartActivity,以便可以将它传递给ActivityManageService,这样ActivityManageService 可以通知Launcher组件进入Pause状态。
Activity类的成员变量mToken的类型是IBinder,它是一个Binder代理对象,指向了ActivityManageService 中一个类型为 ActivityRecord的Binder本地对象,用来维护对应的Activity组件的运行状态以及信息。(并且这个mToken对象是在Activity的attach方法中赋值的)
Launcher组件的成员变量mToken作为参数传递给成员变量mInstrumentation的成员函数execStartActivity, 以便可以将其传递给ActivityManagerService,这样ActivityManagerService接下来就可以获得Launcher组件的详细信息了。
这两个参数比较重要,ApplicationThread参数最终会交给ActivityManagerService,ActivityManagerService会通过ApplicationThread来通知Launcher组件等状态变化,比如进入Paused状态。
mToken是IBinder类型,他是一个Binder代理对象,这个mToken最终会交给ActivityManagerService,通过mToken获取Launcher组件的详细信息。(这个mToken中封装了ActivityRecord对象)。
Activity类的成员变量mToken的类型是IBinder,它是一个Binder代理对象,指向了ActivityManageService 中一个类型为 ActivityRecord的Binder本地对象,用来维护对应的Activity组件的运行状态以及信息。(并且这个mToken对象是在Activity的attach方法中赋值的)。
(每一个已经启动的Activity组件在ActivityManagerService中都有一个对应的ActivityRecord对象,用来维护对应的Activity组件的运行状态和信息)。
通过单例模式获取ActivityManagerService到代理。
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
private static final Singleton IActivityManagerSingleton =
new Singleton() {
@Override
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
ActivityManagerService#startActivity
1.参数caller指向Launcher组件所运行的应用程序进程的Application对象。
2.参数intent包含了即将要启动的MainActivity的组件信息。
3.参数resultTo指向ActivityManagerService内部的一个ActivityRecord对象,它里面保存了Launcher组件的详细信息。
ActivityStarter#startActivityMayWait
1.通过mSupervisor.resolveIntent(intent, resolvedType, userId)获取即将启动Activity组件的更多信息,(PackageManagerServcie解析参数intent的内容)。
2.通过ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
在ActivityManagerService中,每一个应用程序都使用一个ProcessRecord对象来描述,并且保存在ActivityManagerService内部。
3.ActivityStarter类的成员变量mService指向了ActivityManagerService,通过getRecordForAppLocked来获得caller对应的一个ProcessRecord对象callerApp。参数caller指向的是Launcher组件所运行的应用程序进程的一个ApplicationThread对象。
在handlePauseActivity方法中,会将Message对象msg的成员变量obj转换后的SomeArgs中的arg1强制转换成一个IBinder接口。第一件事就是调用成员函数performUserLeavingActivity向Launcher组件发送一个用户离开事件通知,即调用它的成员函数onUserLeaveHint。第二件事就是调用成员函数performPauseActivity向Launcher组件发送一个中止事件通知,即调用它的成员函数onPause。调用QueuedWork类的静态成员函数waitToFinish等待完成前面的一些数据写入操作,例如,将数据写入磁盘的操作。由于现在Launcher组件即将要进入Paused状态了,因此要保证它前面所有数据写入操作都处理完成;否则等它重新进入Resume状态时,就无法恢复之前保存的数据。最后通过ActivityManagerService给它发送的中止Launcher组件的进程间通信请求。
ActivityStack#activityPausedLocked
在这个方法中会调用函数completePauseLocked来执行启动MainActivity组件的操作。并将这个ActivityRecord对象的成员变量state的值设置为ActivityState.PAUSED,表示Launcher组件已经进入了Pause状态了。
ActivityStackSupervisor#startSpecificActivityLocked
检查与ActivityRecord对象r对应的Actiivty组件所需要的应用程序进程是否已经存在。如果存在直接调用realStartActivityLocked函数来启动Actiivty组件。否则先以这个用户ID和进程名称来创建一个应用程序进程,然后再通知这个应用程序进程将Activity组件启动起来。
在ActivityManagerService中,每一个Activity组件都有一个用户ID和一个进程的名称,其中用户ID是在安装Activity组件时由PackageManagerService分配的,而进程名称则是由该Activity组件的android:process属性来决定的。ActivityManagerService在启动一个Activity组件时,首先会以它用户ID和进程名称来检查系统中是否存在一个对应的应用程序进程。如果存在,则会直接通知这个应用程序将该Activity组件启动起来。否则,就会先以这个用户ID和进程名称来创建一个应用程序进程,然后再通知这个应用程序进程将Activity组件启动起来。
ActivityManagerService#startProcessLocked
该方法中依然会检查请求创建的应用程序是否已经存在了,如果不存在。会根据指定的名称以及用于ID来创建一个ProcessRecordLocked对象,同时将其保存到ActivityManagerService类的成员变量mProcessNames。
ActivityManagerServcie#startProcessLocked
得到要创建的应用程序进程的用户ID和用户组ID。调用Process类的静态成员函数start来启动一个新的应用程序进程新的应用程序进程创建成功之后,当前进程会得到一个大于0的进程ID,保存在ProcessStartResult中。调用Process类的静态成员函数start启动一个新的应用程序时,通过entryPoint指定该进程的入口函数为"android.app.ActivityThread"类的静态成员函数main。
同时向ActivityManagerService所在的线程的消息队列中发送一个类型为PROC_START_TIMEOUT_MSG的消息,并且指定这个消息在PROC_START_TIMEOUT之后处理。新的应用程序进程必须在PROC_START_TIMEOUT毫秒之内完成启动工作,并且向ActivityManagerService发送一个完成的通知,以便ActivityManagerService可以在它里面启动一个Activity组件。否则认为超时,就不能将相应的Activity组件启动起来。
新的应用程序在启动时,主要做两件事;
1.在进程中创建一个ActivityThread对象,并且调用它的成员函数attach向ActivityManagerService发送一个启动完成通知。
2.调用Looper类的静态成员函数prepareMainLooper创建一个消息循环,并且在向ActivityManagerService发送启动完成通知之后,使得当前进程进入到这个消息循环中。
主要关注新的应用程序是如何向ActivityManagerService发送一个启动完成通知的。在创建ActivityThread对象thread时,会同时在它内部创建一个ApplicationThread对象mAppThread。前面提到,ActivityThread对象内部的ApplicationThread对象是一个Binder本地对象,ActivityManagerService就是通过它来和应用程序进程通信的。
ActivityManagerService#attachApplicationLocked
参数pid指向了前面所创建是应用程序进程PID,在前面,ActivityManagerService以这个PID为关键字将一个ProcessRecord对象保存在了成员变量mPidsSelfLocked中。通过参数pid将这个ProcessRecord对象取回来,并且保存在变量app中。得到的ProcessRecord对象app就是用来描述新创建的应用程序进程的。初始化ProcessRecord对象app,就是用来描述新创建的应用程序进程的。最重要的就是初始化其thread成员变量,这个IApplicationThread类型的变量,就是ActivityManagerService通过其与新创建的应用程序进行通信的。
ActivityStackSupervisor#attachApplicationLocked
得到位于Activity组件顶端的一个ActivityRecord对象top,它对应的Activity组件就是即将要启动的MainActivity组件。检查这个Activity组价的用户ID和进程名称是否与ProcessRecord对象app所描述的应用程序的用户ID和进程名称一致。如果一致,那么说明ActivityRecord对象top所描述的Activity组件是应该在ProcessRecord对象app所描述的应用程序进程中启动的。
ActivityStackSupervisor#realStartActivityLocked
将该Activity组件添加到参数app所描述的应用程序进程的Activity组件列表中。通知前面创建的应用程序进程启动由参数r所描述的一个Activity组件,即MainActivity。
将Messgae对象msg的成员变量obj转换成一个ActivityClientRecord对象r,接着调用getPackageInfoNoCheck方法获得一个LoadedApk对象,并且保存在ActivityClientRecord对象r的成员变量packageInfo中。
每一个Android应用程序都是打包在一个Apk文件中的。一个Apk文件包含了一个Android应用程序的所有资源,应用程序进程在启动一个Actiivty组件时,需要将它所属的Apk文件加载进来,以便可以访问它里面的资源。在ActivityThread类内部,就使用一个LoadedApk对象来描述一个已经加载的Apk文件。
ActivityThread#handleLaunchActivity
启动由ActivityClientRecord对象r所描述的一个Activity组件。
ActivityThread#performLaunchActivity
创建和初始化一个ContextImpl对象appContext,用来作为所创建的Activity对象activity的运行上下文环境,通过它就可以访问到特定的应用程序资源,以及启动其他的应用程序组件。使用ContextImpl对象appContext和ActiivtyClientRecord对象r来初始化Activity对象activity。最终调用成员变量mInstrumentation的函数callActivityOnCreate将Activity启动起来。
注意:
ActivityClientRecord对象r的成员变量token是一个Ibinder对象,它指向了AcitivityManagerService内部的一个ActivityRecord对象。这个ActivityRecord对象和ActivityClientRecord对象r一样,都是用来描述前面启动的Activity组件的,只不过前者都是在ActivityManagerService中使用,而后者在应用程序中使用。