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對象的視圖內容有一個正確的呈現。