當打開一個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,有一個變化的過程。
文章列表