1前硫、白屏問題
出現(xiàn)問題描述
- Android APP啟動頁面白屏的問題度陆,android開發(fā)app啟動時若沒有做特殊處理的話枉昏,會出現(xiàn)一瞬間的白屏現(xiàn)象晒奕。
- 即使你啟動頁界面就加載一個布局绪氛,不做其他耗時處理唆鸡,貌似也會出現(xiàn)一瞬間的白屏問題。注意枣察,有些地方也稱黑屏争占,主要是看你給app設(shè)置的style樣式。
- 當(dāng)從桌面 Launcher 的小圖標(biāo)點(diǎn)擊冷啟動一個 App 的時候序目,程序需要進(jìn)行一些基本的初始化操作臂痕,例如在Application 或者SplashActivity中做了很多耗時操作,例如初始化第三方SDK等,當(dāng)手機(jī)性能不好猿涨,配置不高時握童,該現(xiàn)象尤其明顯。
為什么存在這個問題
- 當(dāng)系統(tǒng)啟動一個APP時叛赚,zygote進(jìn)程會首先創(chuàng)建一個新的進(jìn)程去運(yùn)行這個APP舆瘪,但是進(jìn)程的創(chuàng)建是需要時間的,在創(chuàng)建完成之前红伦,界面是呈現(xiàn)假死狀態(tài)英古,于是系統(tǒng)根據(jù)你的manifest文件設(shè)置的主題顏色的不同來展示一個白屏或者黑屏。而這個黑(白)屏正式的稱呼應(yīng)該是Preview Window昙读,即預(yù)覽窗口召调。
- 實(shí)際上就是是activity默認(rèn)的主題中的android:windowBackground為白色或者黑色導(dǎo)致的。
- 總結(jié)來說啟動順序就是:app啟動——Preview Window(也稱為預(yù)覽窗口)——啟動頁
2、解決白屏的辦法
解決方案分析
- Android在選擇展示黑屏或者白屏的時候唠叛,是根據(jù)你設(shè)定的主題而不同的只嚣,也就是說,雖然你的代碼沒有被執(zhí)行艺沼,你的配置文件卻被提前讀取了册舞,用來作為展示Preview Window界面的依據(jù)。所以障般,解決方案的切入口就是整個APP的manifest文件调鲸,更確切的說應(yīng)該是主題配置文件。
- 設(shè)置配置文件style樣式中的windowBackground這個屬性來顯示一張背景圖還有一個效果就是啟動應(yīng)用程序會感覺非惩斓矗快藐石,而且與加載MainActivity的contentView是異步的。
第一種解決方案
- 解決辦法:給當(dāng)前啟動頁添加一個有背景的style樣式
設(shè)置style樣式如下:
<style name="SplashTheme" parent="AppTheme">
<item name="android:windowBackground">@mipmap/splash</item>
<item name="android:statusBarColor" tools:ignore="NewApi">@color/white</item>
<item name="android:windowIsTranslucent">true</item>
</style>
注意定拟,在清單文件中:
<activity android:name=".SplashActivity"
android:theme="@style/SplashTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
- 經(jīng)過處理之后App啟動時就不會出現(xiàn)一瞬間白屏的效果
將主題設(shè)置到啟動的Activity的主題中于微,windowBackground就是即將展示的preview window。其中splash可以是一整張圖片青自,它也可以是一個能解析出圖片資源的XML文件株依。 - 該方案注意要點(diǎn)
給Preview Window設(shè)置的背景圖如果不做處理,圖片就會一直存在于內(nèi)存中延窜,所以勺三,當(dāng)我們進(jìn)入到歡迎頁的時候,不要忘了把背景圖設(shè)置為空
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
//將window的背景圖設(shè)置為空
getWindow().setBackgroundDrawable(null);
super.onCreate(savedInstanceState);
}
這樣操作如何屏幕適配呢需曾?
- 這樣通過樣式style設(shè)置SplashActivity加載圖,不能像imageView那樣可以設(shè)置縮放功能祈远,因此可以采用.9圖片呆万。
- 直接設(shè)置圖,沒有做適配车份,也無傷大雅谋减,具體要看UI要求呢!
第二種解決方案
- 禁止加載Preview Window扫沼,具體做法如下:
<style name="SplashTheme" parent="@style/Theme.AppCompat.Light.NoActionBar">
<item name="android:windowDisablePreview">true</item>
</style>
設(shè)定為啟動的Activity的主題出爹,即可禁止Preview Window,當(dāng)然缎除,也有人通過把preview window設(shè)置為全透明严就,也達(dá)成了類似的效果。個人感覺這種方法沒有第一種好器罐!
- windowDisablePreview的作用
通過設(shè)置android:windowDisablePreview屬性梢为,禁用窗口的預(yù)覽動畫,在SplashActivity顯示之前,系統(tǒng)永遠(yuǎn)不會使用窗口的主題來顯示它的預(yù)覽铸董,這也保證了不會出現(xiàn)白屏或者黑屏祟印。但是,與設(shè)置android:windowIsTranslucent屬性一樣粟害,如果在SplashActivity啟動的時候蕴忆,有過多復(fù)雜的操作,就會出現(xiàn)在手機(jī)中點(diǎn)擊了應(yīng)用程序的圖標(biāo)悲幅,但過n秒才會打開應(yīng)用程序不好的卡頓體驗(yàn)效果套鹅。 - 這種方法有個小缺點(diǎn),就是點(diǎn)擊后短暫的那幾百毫秒沒有反應(yīng)夺艰,就好像“假死”了一樣芋哭,過了一會兒才跳出我們應(yīng)用程序的第一個Activity,如果你不想讓你的 App 有這個短暫“假死”時間郁副,建議使用第一種方法减牺。
Application啟動速度優(yōu)化
提高app的啟動速度,加快Application的執(zhí)行時間也是一個很重要的方面存谎,這里我暫時總結(jié)了幾條原則:
- 盡量不將一些業(yè)務(wù)邏輯放于Application中拔疚;
- Application盡量不以靜態(tài)變量的方式保存應(yīng)用數(shù)據(jù);
- 若App的大小不是特別大無需使用dex分包方案既荚;
- 在Application中關(guān)于文件稚失,數(shù)據(jù)庫等耗時的操作盡量放到IntentService線程中處理
- 不要做有關(guān)于循環(huán)的操作
啟動頁面屏蔽返回按鍵
一般App中都會在啟動頁面執(zhí)行一些初始化配置等,所以這時候啟動頁加載時不希望用戶通過按下返回按鍵退出App恰聘,因而可以在啟動頁中屏蔽返回按鍵句各,這里簡單的介紹一下具體的實(shí)現(xiàn):
/**
* Activity屏蔽物理返回按鈕
*
* @param keyCode
* @param event
* @return
*/
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
return true;
}
return super.onKeyDown(keyCode, event);
}