閃屏原因剖析StartingWindow(Preview Window)
我們正常開發中會在Activity的onCreate()方法中調用setContentView(View)設置該Activity的顯示佈局,那麼問題就來了,既然我們設置了佈局,爲什麼啓動的時候還會白屏或者黑屏而不是顯示我set的佈局呢?下面就帶領大家一起來剖析一下原因。
當打開一個Activity時,如果這個Activity所屬Application還沒有在運行,系統會爲這個Activity的創建一個進程(每開啓一個進程都會有一個Application,所以Application的onCreate()可能會被調用多次),但進程的創建與初始化都需要時間,在這個動作完成之前,如果初始化的時間過長,屏幕上可能沒有任何動靜,用戶會以爲沒有點到按鈕。所以既不能停在原來的地方又沒到顯示新的界面,怎麼辦呢?這就有了StartingWindow(也稱之爲PreviewWindow)的出現,這樣看起來就像Activity已經啓動起來了,只是數據內容還沒有初始化好。
StartingWindow一般出現在應用程序進程創建並初始化成功前,所以它是個臨時窗口,對應的WindowType是TYPE_APPLICATION_STARTING。目的是告訴用戶,系統已經接受到操作,正在響應,在程序初始化完成後實現目的UI,同時移除這個窗口。
這個StartingWindow就是我們要討論的白屏和黑屏的“元兇”,一般情況下我們會對Application和Activity設置Theme,系統會根據設置的Theme初始化StartingWindow。Window佈局的頂層是DecorView,StartingWindow顯示一個空DecorView,但是會給這個DecorView應用這個Activity指定的Theme,如果這個Activity沒有指定Theme就用Application的(Application系統要求必須設置Theme)。
方法一:
1、在style.xml自定義一個主題,設置如下:
<style name="SplashTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowNoTitle">true</item>
</style>
2、打開Manifest文件,找到啓動的Activity
SplashActivity的實現,在onCreate()啓動你的MainActivity即可,其他什麼都別幹:
方法二:
1、給主題設置Window
背景:
<style name="SplashTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowBackground">@drawable/flash</item>
<item name="android:windowFullscreen">true</item>
</style>
2、打開Manifest文件,找到啓動的Activity
android:theme="@style/SplashTheme"
3、SplashActivity的實現,在onCreate()啓動你的MainActivity即可:
public class SplashActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
startActivity(new Intent(this, MainActivity.class));
finish();
}
}
特別注意:爲保證啓動速度,SplashActivity
不要調用setContentView()
方法。因爲Activity
設置了layout
,它在App
完全初始化完成後纔會顯示,也會耗時。
參考文章:https://blog.csdn.net/yanzhenjie1003/article/details/52201896