天天看點

Android首次啟動黑屏白屏優化(windowBackground)

有關于Android第一次啟動出現的黑屏和白屏的過渡問題,看了很多相關的資料和文章,決定将自己的一些見解和處理方式總結一下,以便日後在遇到有個思路,先大緻列為幾個部分。

一:應用點選啟動的過程描述和冷熱啟動的概念

手機本身的桌面也是一個應用,所有的應用圖示在桌面上的點選事件就像是應用中的控件OnCLick點選事件一樣,都是處于使用者點選的時候監聽的狀态,一個應用在桌面上被使用者點選之後到啟動是一個複雜的過程,對這個過程描述比較詳細的文章:https://blog.csdn.net/qian520ao/article/details/78156214可供參考。大緻過程就是

1、Launcher通知AMS啟動APP的MainActivity,也就是清單檔案設定啟動的Activity。

2、AMS記錄要啟動的Activity資訊,并且通知Launcher進入pause狀态。

3、Launcher進入pause狀态後,通知AMS已經paused了,可以啟動了。

4、app未開啟過,是以AMS啟動新的程序,并且在新程序中建立ActivityThread對象,執行其中的main函數方法。

5、app主線程啟動完畢後通知AMS,并傳入applicationThread以便通訊。

6、AMS通知綁定Application并啟動MainActivity。

7、啟動MainActivitiy,并且建立和關聯Context,最後調用onCreate方法。

在這裡要插入一個概念,在啟動整個應用的過程中,就會因不同情況出現冷啟動和熱啟動兩種,冷啟動就是在啟動該應用前,系統中沒有該應用的任何程序資訊。 (第一次打開應用、殺死了程序再打開、時間最長)熱啟動則是使用者使用傳回鍵推出應用,然後馬上又重新啟動應用。二者的差別是冷啟動沒有建立過初始化,熱啟動是已經初始化再打開。

二:為什麼會首次加載出現白屏或者黑屏的效果

說完啟動過程,就要來說明一下為什麼會出現白屏或者黑屏的問題。在應用冷啟動和熱啟動的過程中,總歸是要建立這個應用程序的,是以在這個過程中Google為了增加使用者的體驗,就做了一個過渡效果的Windows視窗,這個Windows視窗效果根據你設定的啟動頁面的主題來顯示,如果你設定的主題是Light則過渡視窗是預設白屏,反之則是預設黑屏,當應用第一次加載打開或者程序被殺死重新啟動的時候(冷啟動),那麼這個過渡視窗就會顯示較長時間,熱啟動則會一閃而過,總之黑屏和白屏的産生,就是這樣來的

三:如何去優化這個過程

優化的方法網上有很多,經過每個方法的嘗試和實踐測試,有一個自己的方式來實作,另外結尾會歸納一下其他幾種方式不采納的原因

我的方式是通過設定

Style.Xml主題

<!-- 啟動頁主題 -->
<style name="StartAppTheme" parent="@android:style/Theme.NoTitleBar.Fullscreen">
    <item name="android:windowBackground">@drawable/xxxxx</item>
    <item name="android:windowIsTranslucent">false</item>
</style>      
設定清單檔案AndroidManifest.Xml
<activity
    android:name=".activity.xxxxxActivity"
    android:label="@string/xxxxx"
    android:screenOrientation="portrait"
    android:theme="@style/StartAppTheme">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>      

引用xxxxx的drawable檔案

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:bottom="xxxdp">
        <color android:color="#ffffff" />
    </item>
    <item>
        <color android:color="#ffffff" />
    </item>
    <item android:bottom="xxxdp">
        <bitmap
            android:gravity="bottom|center_horizontal"
            android:src="@drawable/你的logo圖檔" />
    </item>

    <item android:bottom="xxxdp">
        <bitmap
            android:gravity="bottom|center_horizontal"
            android:src="@drawable/你的logo圖檔" />
    </item>

</layer-list>
      

這裡之是以用自定義的drawable,是因為我們沒有現成的啟動圖檔,而且為了和随後啟動的廣告頁面保持一緻,是以采用了一個白背景加Logo底的自定義效果,這樣當廣告頁加載的時候可以平穩無差别過渡。關于Android中layer-list使用,也可以搜到大部分文章,這裡隻簡單講一下layer-list是将多個drawable按照順序層疊在一起顯示,預設情況下,所有的item中的drawable都會自動根據它附上view的大小而進行縮放,

layer-list中的item是按照順序從下往上疊加的,即先定義的item在下面,後面的依次往上面疊放。是以有了如上的自定義Drawable效果

附:

使用方案

<item name="android:windowIsTranslucent">true</item>将過渡視窗設定成無,即透明效果,這種方式如果遇到手機硬體配置好的情況,可能會平穩啟動應用,并且無黑屏閃顯,但是如果遇到配置很差的手機,會出現使用者點選後卡在原地很久才打開應用的錯覺,其實隻是過渡效果透明了,是以為了不影響使用者體驗,還是建議不使用
      

使用方案

<style name="StartAppTheme" parent="@android:style/Theme.NoTitleBar.Fullscreen">
    <item name="android:windowBackground">@drawable/圖檔</item>
    <item name="android:windowIsTranslucent">false</item>
</style>      

雖然可以用一張圖檔替換過渡效果,并且效果不錯,但是如果啟動頁和該圖檔有大的出入,會給使用者一種視差,不能起到平穩過度的感覺

使用方案

getActivity().getWindow().getDecorView().setBackground(new BitmapDrawable(blurBitmap));

動态去替換過渡頁,沒有嘗試過,不過感覺過渡界面本身沒那麼複雜多變,而且将動态設定放在執行類中,也擔心可能無效,是以并沒做過多嘗試

繼續閱讀