LocalActivityManager内部机制的核心在于,它使用了主线程对象mActivityThread来装载指定的Activity。注意,这里是装载,而不是启动,这点很重要。函数
所谓的启动,通常是指会建立一个进程(若是所在应用进程还不存在)运行该Activity,而装载仅仅是指把该Activity做为一个普通类进行加载,并建立一个该类的对象而已,而该类的任何函数都没有被运行。spa
LocalActivityManager提供了一个重要方法startActivity(),该方法正是利用主线程mActivityThread去装载指定的Activity,其执行过程如图10-25所示。线程
Manager对象必须已经被初始化,初始化的工做是在dispatchCreate()方法中首先被完成的,而这又是在ActivityGroup类中的onCreate()中被调用的。也就是说,LocalActivityManager的startActivity()方法必须在所在的Activity的onCreate()方法执行完毕后被调用。orm
判断目标Activity是否包含在该Manager中。Manager中使用两个列表变量保存已经装载过的Activity对象,分别是mActivities和mActivityArray。前者是一个HashMap类型,每个LocalActivityRecord按照一个字符串对应;后者是一个ArrayList列表。对象
判断装载的Activity对象是否有正处于resume状态的,若是有,则要先暂停,事实上能够彻底不用暂停,暂停仅仅是Manager但愿彻底按照Activity对象自己的执行顺序调用它,从而使得看上去更像是一个标准的子Activity启动方式。而暂停则是经过调用moveToState()完成的。blog
若是目标Activity已经被装载到了当前Manager中,下面就须要判断是直接使用该Activity的当前窗口呢,仍是须要先销毁该Activity,并从新调用其onCreate()?注意,这里所说的销毁仅仅是指把Activity变成"销毁"的状态而已,并非说销毁该Activity对象。而判断的规则有点相似于AmS中根据Activity的flag执行不一样的操做,其中包括是否先调用目标Activity的onNewIntent(),还包括是不是CLEAR_TOP模式。通常做为TabActivity的嵌入式Activity都不会是CLEAR_TOP模式,不然,若是多个Tab页使用同一个Activity对象将致使所显示的内容彻底相同。进程
调用moveToState()改变指定Activity到resume状态。ci
返回Activity所对应的Window窗口。字符串
从以上步骤能够看出,装载Activity对象的过程对AmS来说是彻底不可见的,由于这是装载而不是启动,所以看似TabActvity同时运行了多个Activity,而实际上仅仅是运行了ActivityGroup一个Activity。那些嵌入的Activity仅仅是贡献了本身所包含的Window窗口而已,TabActivity正是把这些Window窗口的DecorView做为tabcontent的子视图而已。it
下面对moveToState(LocalActivityRecord r, int desireState)函数的过程进行说明,参数r表明目标Activity对象,desireState表明指望把目标Activity改变成哪一种状态。
moveToState()函数内部首先判断r.curState是不是RESTORED或者DESTROY状态,若是是则直接返回。由于RESTORED表明刚刚建立了目标Activity对象,尚未执行onCreate()方法,因此不能改变状态;DESTROY表明已经销毁,也不能改变状态。
接着,判断r.curState是不是INITIALIZE状态,这种状况只有在第一次调用startActivity()装载目标Activity对象时才会执行到,其内部主要包括调用startActivityNow()和performResumeActivity()将目标Activity改变到STARTED或者RESUMED状态。
因为Activity当前状态不一样,要想达到不一样的指望状态天然须要通过不一样的步骤。moveToState()函数内部正是使用switch语句先判断当前处于什么状态,而后再在case里面使用if…else语句判断指望的状态,最后再调用不一样的函数。其状态和调用关系如表10-8所示,该表中调用的函数名称使用了简写,好比performRestartActivity简写为Restart。
表10-8 Activity在不一样状态中转换时需执行的操做
目标状态 当前状态 |
CREATED |
STARTED |
RESUMED |
CREATED |
|
Restart (); |
Restart(); Resume(); |
STARTED |
Stop(); |
|
Resume(); |
RESUMED |
Pause(); Stop(); |
Pause(); |
|
从以上的步骤能够看出,startActivity()的内部执行逻辑有点像AmS中根据当前Activity状态调用不一样方法。这二者就像《西游记》中的小雷音寺和大雷音寺,二者的本质区别在于LocalActivityManager仅仅是为了获取Activity对应的Window对象,中间的状态切换仅仅是为了保证Activity自己的执行过程,从而保证Window对象的视图内容有一个正确的呈现。