(八)App内部的頁面跳轉
在介紹完App的啟動流程後,我們發現,其實就是啟動一個App的首頁。
接下來我們看App内部頁面的跳轉。
從ActivityA跳轉到ActivityB,其實可以把ActivityA看作是Launcher,那麼這個跳轉過程,和App的啟動過程就很像了。
有了前面的分析基礎,會發現,這個過程不需要重新啟動一個新的程序,是以可以省略App啟動過程中的一些步驟,流程簡化為:
1)ActivityA向AMS發送一個啟動ActivityB的消息。
2)AMS儲存ActivityB的資訊,然後通知App,你可以休眠了(onPaused)。
3)ActivityA進入休眠,然後通知AMS,我休眠了。
4)AMS發現ActivityB所在的程序就是ActivityA所在的程序,是以不需要重新啟動新的程序,是以它就會通知App,啟動ActivityB。
5)App啟動ActivityB。
不想看上述文字的,看我畫的這個圖:

整體流程我就不多說了,和上一篇文章介紹的App啟動流程是基本一緻的。
以上的分析,僅限于ActivityA和ActivityB在相同的程序中,如果在Manifest中指定這兩個Activity不在同一個程序中,那麼就又是另一套流程了,但是整體流程大同小異。
(九)Context家族史
Activity和Service都有Context,這三個類,還有Application,其實是親戚一家子。
Activity因為有了一層Theme,是以中間有個ContextThemeWrapper,相當于它是Service和Application的侄子。
ContextWrapper隻是一個包裝類,沒有任何具體的實作,真正的邏輯都在ContextImpl裡面。
一個應用包含的Context個數:Service個數+Activity個數+1(Application類本身對應一個Context對象)。
應用程式中包含多個ContextImpl對象,而其内部變量mPackageInfo指向同一個PackageInfo對象。
- - - - - - - - - - - - - 華麗的分割線,以下是例子- - - - - - - - - - - - - - - - - - - -
我們就拿Activity舉例子,看看Activity和Context的聯系和差別。
我們知道,跳轉到一個新的Activity要這麼寫:
我們還知道,也可以在Activity中使用getApplicationContext方法擷取Context上下文資訊,然後使用Context 的startActivity方法,啟動一個新的Activity:
這二者的差別是什麼?我們畫個圖,就看明白了:
因為Context的startActivity方法,我看了在ContextImpl中的源碼實作,仍然是從ActivityThread中取出Instrumentation,然後執行execStartActivity方法,這和使用Activity的startActivity方法的流程是一樣的。
還記得我們前面分析的App啟動流程麼?在第五階段,建立App程序的時候,先建立的ActivityThread,再建立的Application。Application的生命周期是跟着整個App走的。
而getApplicationContext得到的Context,就是從ActivityThread中取出來的Application對象,是以這個Context上下文,使用時要當心,容易引起記憶體洩露。
下一篇文章,我們就要邁進Service的世界了。