天天看點

寫給Android App開發人員看的Android底層知識(4)

(八)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。

      不想看上述文字的,看我畫的這個圖:

寫給Android App開發人員看的Android底層知識(4)

整體流程我就不多說了,和上一篇文章介紹的App啟動流程是基本一緻的。

      以上的分析,僅限于ActivityA和ActivityB在相同的程序中,如果在Manifest中指定這兩個Activity不在同一個程序中,那麼就又是另一套流程了,但是整體流程大同小異。

      (九)Context家族史

      Activity和Service都有Context,這三個類,還有Application,其實是親戚一家子。

寫給Android App開發人員看的Android底層知識(4)

Activity因為有了一層Theme,是以中間有個ContextThemeWrapper,相當于它是Service和Application的侄子。

      ContextWrapper隻是一個包裝類,沒有任何具體的實作,真正的邏輯都在ContextImpl裡面。

一個應用包含的Context個數:Service個數+Activity個數+1(Application類本身對應一個Context對象)。

應用程式中包含多個ContextImpl對象,而其内部變量mPackageInfo指向同一個PackageInfo對象。

- - - - - - - - - - - - - 華麗的分割線,以下是例子- - - - - - - - - - - - - - - - - - - -

      我們就拿Activity舉例子,看看Activity和Context的聯系和差別。

      我們知道,跳轉到一個新的Activity要這麼寫:

寫給Android App開發人員看的Android底層知識(4)

我們還知道,也可以在Activity中使用getApplicationContext方法擷取Context上下文資訊,然後使用Context 的startActivity方法,啟動一個新的Activity:

寫給Android App開發人員看的Android底層知識(4)

這二者的差別是什麼?我們畫個圖,就看明白了:

寫給Android App開發人員看的Android底層知識(4)

      因為Context的startActivity方法,我看了在ContextImpl中的源碼實作,仍然是從ActivityThread中取出Instrumentation,然後執行execStartActivity方法,這和使用Activity的startActivity方法的流程是一樣的。

      還記得我們前面分析的App啟動流程麼?在第五階段,建立App程序的時候,先建立的ActivityThread,再建立的Application。Application的生命周期是跟着整個App走的。

      而getApplicationContext得到的Context,就是從ActivityThread中取出來的Application對象,是以這個Context上下文,使用時要當心,容易引起記憶體洩露。

寫給Android App開發人員看的Android底層知識(4)

下一篇文章,我們就要邁進Service的世界了。