當開啟一個Activity時,如果這個Activity所屬的應用還沒有在執行,系統會為這個Activity所屬的應用建立一個程式,但程式的建立與初始化都需要時間,在這個動作完成之前系統要做什麼呢?如果沒有任何反應的話,如果程式初始化的時間很長,使用者可能還以為沒有點到相應的位置。但此時所啟動的程式還沒初始化完,既無法顯示程式,又不能停在原處不做任何動作,怎麼辦?這就有了Starting Window的概念,也可以稱之為Preview Window。
Starting Window就是一個用於在應用程式程式建立並初始化成功前顯示的臨時視窗,擁有的Window Type是TYPE_APPLICATION_STARTING。在程式初始化完成前顯示這個視窗,以告知使用者系統已經知道了他要開啟這個應用並做出了響應,當程式初始化完成後顯示使用者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,有一個變化的過程。