當開啟一個Activity時,如果這個Activity所屬的應用還沒有在運行,系統會為這個Activity所屬的應用建立一個進程,但進程的建立與初始化都需要時間,在這個動作完成之前系統要做什麼呢?如果沒有任何反應的話,如果程式初始化的時間很長,使用者可能還以為沒有點到相應的位置。但此時所啟動的程式還沒初始化完,既無法顯示程式,又不能停在原處不做任何動作,怎麼辦?這就有了Starting Window的概念,也可以稱之為Preview Window。
Starting Window就是一個用於在應用程式進程建立並初始化成功前顯示的臨時視窗,擁有的Window Type是TYPEAPPLICATIONSTARTING。在程式初始化完成前顯示這個視窗,以告知使用者系統已經知道了他要開啟這個應用並做出了響應,當程式初始化完成後顯示使用者UI並移除這個視窗。
這個Starting Window我們都見過,不過可能沒留意過,其實就是開啟程式時黑屏的那個視窗,夠醜的。不過也沒辦法,每個程式的介面都不是同的,系統只有預設顯示一個很簡單的視窗了。
如果所謂的Starting Window只是一個黑屏的視窗的話,那這個功能未免也太雞肋了。其實系統是可以根據每個程式的Theme顯示不同的樣子的。
啟動應用的時候,雖然我們的程式還沒初始化,但程式內的組件可是在程式安裝的時候就被系統分析註冊了的。我們可以針對每個Application和Activity設定不同的Theme,系統就是根據這個Theme初始化Starting Window的。Window布局的頂層是DecorView,Starting Window就是顯示一個空的但是應用了Activity指定的Theme(如果Activity沒有指定就用Application的)的DecorView。
在Theme中可以指定很多東西,如ActionBar的樣式,視窗的背景,Activity的表徵圖等,通過給Activity指定Theme,系統就可以在我們的應用初始化完成之前將這個Theme應用到Starting Window,這樣看起來就像我們的應用已經啟動起來了,只是資料內容還沒有初始化好。
所以,如果你的Activity的背景只是簡單的純色的話,最好直接通過Theme把它應用到Activity的Background,而不是設定為頂層Layout的背景,如果真的需要給頂層Layout設定背景,也可以給android:windowBackground設定一個和Activity UI相似的背景,為了防止Overdraw,在Activity的onCreate中通過setWindowBackground()再把視窗的背景設定為null。
系統在顯示Activity前顯示一個Starting Window僅發生在需要為啟動這個Activity建立進程時,一般情況下是一個應用的入口Activity(包含Lanuncher中顯示的表徵圖進入的Activity及被其他應用調用的Activity)。
還有一種情況就是應用內有多個進程的情況(通過android:process),比如你的程式需要用單獨的進程查看圖片,當從你的應用的主進程進入圖片瀏覽的Activity時,系統就會建立圖片瀏覽的進程,如果圖片瀏覽的Activity的需要使用的表徵圖和Application指定的表徵圖不一樣的話就要注意了,系統顯示圖片進程中的Activity的Starting Window時不會使用這個Activity在Manifest中通過android:icon指定的表徵圖,而只會使用Theme中指定的表徵圖,如果沒為這個Activity指定一個Theme或所指定的Theme中沒有指定android:icon的話,系統會使用Application標籤指定的android:icon,結果就是會看到Starting Window中顯示一個表徵圖,當Activity載入完後表徵圖會變為Activity在Manifest中指定的android:icon,有一個變化的過程。
更多介紹參考Android App Launching Made Gorgeous