android app啟動(dòng)頁(閃屏頁)白屏快速優(yōu)化方案實(shí)踐

1.背景

無意間發(fā)現(xiàn),自己的一個(gè)線上項(xiàng)目雖然很輕量級(jí),但是在低端機(jī)型上依然存在啟動(dòng)頁白屏現(xiàn)象善涨,于是就快速優(yōu)化了一番掏婶,在此分享一下優(yōu)化方案啃奴。

2.存在問題

引用一張探索 Android 啟動(dòng)優(yōu)化方法中的app冷啟動(dòng)流程示意圖:

ILQ5nr.png

由啟動(dòng)圖可知:打開app時(shí),系統(tǒng)要加載一個(gè)空白window雄妥,創(chuàng)建進(jìn)程最蕾,初始化app(啟動(dòng)應(yīng)用),最后才加載啟動(dòng)頁布局老厌。如果在創(chuàng)建進(jìn)程和初始化app過程中耗時(shí)較久瘟则,那么在啟動(dòng)頁布局顯示之前,用戶便能肉眼感知到空白window的存在枝秤,也就是我們所說的白屏(或者黑屏醋拧,由你設(shè)置的theme決定)。

本文要做的,一步一步解決顯示白屏的問題丹壕。

3.特別說明

本文就不聊zygote創(chuàng)建進(jìn)程運(yùn)行app的那一堆原理來班門弄斧了庆械,只談一談解決問題最簡單的方法,對原理有興趣的可以自行翻閱【參考文獻(xiàn)】中的相關(guān)文檔雀费。

4.解決思路

通過給activity指定帶有window背景的theme來避免白屏(設(shè)置window背景)

優(yōu)點(diǎn) 缺點(diǎn)
設(shè)置window背景 能夠快速解決顯示白屏問題 可能會(huì)引起背景圖拉伸問題

5.快速解決方案

創(chuàng)建一個(gè)style干奢,清單文件里單獨(dú)給啟動(dòng)頁的theme設(shè)置為該style,代碼如下:

<style name="AppTheme.Splash" parent="Theme.AppCompat.DayNight.NoActionBar">
    <!--將頂部狀態(tài)欄設(shè)置為透明盏袄,并將界面內(nèi)容布局上邊界上提至狀態(tài)欄頂部-->
    <item name="android:windowTranslucentStatus">true</item>
    <!--如果有底部虛擬導(dǎo)航欄忿峻,則將底部虛擬導(dǎo)航欄設(shè)置為透明,并將界面內(nèi)容布局下邊界下沉至虛擬導(dǎo)航欄底部-->
    <item name="android:windowTranslucentNavigation">true</item>
    <!--給window窗口設(shè)置背景圖-->
    <item name="android:windowBackground">@drawable/bg_splash_snow</item>
</style>

@drawable/bg_splash_snow改為你自己的背景圖

啟動(dòng)頁activity 的 onCreate 方法回調(diào)中辕羽,將window的背景圖置空逛尚,代碼如下:

class SplashActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        window.setBackgroundDrawable(null)
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_splash)
    }
}

看下效果:

啟動(dòng)頁示例2.gif

完事兒~~~下篇見

8c0de91c98bf76faca5055cabcb56a3c03a98e398fdef5f7a.jpg

這就沒了?刁愿?绰寞??铣口?

aae06983740640ab814d991af8898f9c67612a9391d499944.jpg

對滤钱,沒錯(cuò),代碼就是這么簡單脑题。

不過對style里那三個(gè)屬性不熟悉的朋友件缸,可能心存疑問:這到底是個(gè)什么鬼。叔遂。他炊。

那咱接下來就細(xì)細(xì)的捋一遍吧。

6.事前準(zhǔn)備

創(chuàng)建一個(gè)啟動(dòng)頁界面已艰,布局里設(shè)置背景為一張圖片痊末,并放一個(gè)textview:

class SplashActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_splash)
    }
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/bg_splash_snow"
    tools:context=".activity.SplashActivity">

    <androidx.appcompat.widget.AppCompatTextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="100dp"
        android:text="@string/app_name"
        android:textColor="@color/white"
        android:textSize="22sp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

styles文件里新建一個(gè) style ,parent 設(shè)置為 Theme.AppCompat.DayNight.NoActionBar 來取消標(biāo)題欄:

<style name="AppTheme.Splash" parent="Theme.AppCompat.DayNight.NoActionBar">
</style>

AndroidManifest.xml里將該style設(shè)置給SplashActivity哩掺,方便我們后續(xù)對比效果:

<activity android:name=".activity.SplashActivity"
    android:theme="@style/AppTheme.Splash">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />

        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

華為手機(jī)上運(yùn)行效果如下:

5ad43f16d970f580f925f31f65fbd2c.jpg

咦凿叠?這頂部狀態(tài)欄跟底部導(dǎo)航欄也忒丑了點(diǎn)。嚼吞。盒件。。誊薄。。

D415A583C0FF67A7D583065D4701F7BE.jpg

那锰茉。呢蔫。干掉吧。。片吊。

1407C31B0C9096C6B3967DE5631B0B63.gif

在style里設(shè)置一下:

<style name="AppTheme.Splash" parent="Theme.AppCompat.DayNight.NoActionBar">
    <!--將頂部狀態(tài)欄設(shè)置為透明绽昏,并將界面內(nèi)容布局上邊界上提至狀態(tài)欄頂部-->
    <item name="android:windowTranslucentStatus">true</item>
    <!--如果有底部虛擬導(dǎo)航欄,則將底部虛擬導(dǎo)航欄設(shè)置為透明俏脊,并將界面內(nèi)容布局下邊界下沉至虛擬導(dǎo)航欄底部-->
    <item name="android:windowTranslucentNavigation">true</item>
</style>

運(yùn)行效果如下:

啟動(dòng)頁示例.gif

哦豁 ~~ 處理好頂部狀態(tài)欄跟底部導(dǎo)航欄后舒服多了全谤,但是,這個(gè)白屏問題爷贫?认然??

恩漫萄,明顯的不像話卷员。

7.通過【設(shè)置window背景】解決白屏問題

這個(gè)賊簡單,只需要通過style的android:windowBackground屬性給window設(shè)置一個(gè)背景腾务,最終設(shè)置如下:

<style name="AppTheme.Splash" parent="Theme.AppCompat.DayNight.NoActionBar">
    <!--將頂部狀態(tài)欄設(shè)置為透明毕骡,并將界面內(nèi)容布局上邊界上提至狀態(tài)欄頂部-->
    <item name="android:windowTranslucentStatus">true</item>
    <!--如果有底部虛擬導(dǎo)航欄,則將底部虛擬導(dǎo)航欄設(shè)置為透明岩瘦,并將界面內(nèi)容布局下邊界下沉至虛擬導(dǎo)航欄底部-->
    <item name="android:windowTranslucentNavigation">true</item>
    <!--給window窗口設(shè)置背景圖-->
    <item name="android:windowBackground">@drawable/bg_splash_snow</item>
</style>

@drawable/bg_splash_snow 是我的一張背景圖:

bg_splash_snow.png

運(yùn)行效果如下:

啟動(dòng)頁示例2.gif

完事兒未巫,收工~

“等等~”,有朋友(無中生友启昧?)怕是要問了:那你這一個(gè)界面設(shè)置了兩個(gè)背景圖叙凡,豈不是有些冗余?

哎呀箫津,那來吧狭姨,去掉一張吧,把布局文件的圖干掉(tools:background表示只渲染預(yù)覽布局苏遥,不參與實(shí)際運(yùn)行):

image-20210610170155306.png

結(jié)果如下:

啟動(dòng)頁示例2.gif

可以看到饼拍,運(yùn)行結(jié)果跟之前跟一模一樣。

眼尖的朋友又要問了:“連時(shí)間都一樣田炭?师抄??”

哈哈哈教硫,我就是偷的上一張圖叨吮。

47915A4C88384FBDB3496D2D7C544FA5.gif

當(dāng)然了,這里顯示的背景圖就是window上的背景圖瞬矩,實(shí)際上這樣是有問題的茶鉴,比如我啟動(dòng)頁要放個(gè)viewpager啥的,需要處理圖片的一些展示邏輯可咋整景用,window背景又不能搞成viewpager涵叮?

那咱們換一個(gè)思路,window的背景圖在用完后給他置空,繼續(xù)顯示啟動(dòng)頁的布局視圖行不行呢割粮?來實(shí)踐一下看看:

class SplashActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        // 置空window背景圖
        window.setBackgroundDrawable(null)
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_splash)
    }
}

運(yùn)行效果如下:

啟動(dòng)頁示例3.gif

這什么鬼盾碗,黑屏了?哦舀瓢,忘了給背景圖加回去了哈哈哈廷雅,再來再來:

image-20210610172320282.png

再運(yùn)行一下看看效果:

啟動(dòng)頁示例4.gif

這下OK了,通過將window背景圖設(shè)置成一個(gè)臨時(shí)圖片京髓,既解決了重復(fù)引用圖片資源的問題航缀,又可以正常執(zhí)行啟動(dòng)頁自己的邏輯了。

【特別注意】

由于window背景使用圖片時(shí)無法像imageView一樣設(shè)置縮放朵锣,所以會(huì)強(qiáng)制將圖片拉伸為屏幕寬高谬盐,從而導(dǎo)致圖片變形。要避免這種情況出現(xiàn)诚些,可以嘗試使用點(diǎn)九圖【9-Patch圖】或者自定義的drawable圖來處理飞傀,這里就需要仁者見仁智者見智了。

8.總結(jié)

解決app啟動(dòng)頁白屏的方案不止一種诬烹,我們這里采用了最直觀明了的做法砸烦,即使用圖片替換白屏的方式,但是要明白绞吁,這種做法僅僅是替換了白屏幢痘,并沒有消除白屏展示占用的時(shí)間。由app冷啟動(dòng)流程可知家破,空白window(即白屏)時(shí)間主要由創(chuàng)建進(jìn)程和初始化app(即啟動(dòng)應(yīng)用)來決定颜说,雖然我們無法干預(yù)創(chuàng)建進(jìn)程的時(shí)間,但可以從初始化app來下手汰聋,比如優(yōu)化自定義的application门粪,從而縮短白屏顯示時(shí)間,加快應(yīng)用啟動(dòng)速度烹困。

參考文獻(xiàn)

探索 Android 啟動(dòng)優(yōu)化方法

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末玄妈,一起剝皮案震驚了整個(gè)濱河市砰逻,隨后出現(xiàn)的幾起案子谆棱,更是在濱河造成了極大的恐慌,老刑警劉巖震捣,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件枯饿,死亡現(xiàn)場離奇詭異酝锅,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)奢方,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進(jìn)店門搔扁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來擒权,“玉大人,你說我怎么就攤上這事阁谆。” “怎么了愉老?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵场绿,是天一觀的道長。 經(jīng)常有香客問我嫉入,道長焰盗,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任咒林,我火速辦了婚禮熬拒,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘垫竞。我一直安慰自己澎粟,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布欢瞪。 她就那樣靜靜地躺著活烙,像睡著了一般。 火紅的嫁衣襯著肌膚如雪遣鼓。 梳的紋絲不亂的頭發(fā)上啸盏,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天,我揣著相機(jī)與錄音骑祟,去河邊找鬼回懦。 笑死,一個(gè)胖子當(dāng)著我的面吹牛次企,可吹牛的內(nèi)容都是我干的怯晕。 我是一名探鬼主播,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼抒巢,長吁一口氣:“原來是場噩夢啊……” “哼贫贝!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蛉谜,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤稚晚,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后型诚,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體客燕,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年狰贯,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了也搓。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片赏廓。...
    茶點(diǎn)故事閱讀 38,100評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖傍妒,靈堂內(nèi)的尸體忽然破棺而出幔摸,到底是詐尸還是另有隱情,我是刑警寧澤颤练,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布既忆,位于F島的核電站,受9級(jí)特大地震影響嗦玖,放射性物質(zhì)發(fā)生泄漏患雇。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一宇挫、第九天 我趴在偏房一處隱蔽的房頂上張望苛吱。 院中可真熱鬧,春花似錦器瘪、人聲如沸翠储。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽彰亥。三九已至,卻和暖如春衰齐,著一層夾襖步出監(jiān)牢的瞬間任斋,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工耻涛, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留废酷,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓抹缕,卻偏偏與公主長得像澈蟆,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子卓研,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評論 2 345

推薦閱讀更多精彩內(nèi)容