(八)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的世界了。
文章列表