Android之路 - 冷啟動解決方案:實現秒開
前言
關於splash頁面相信每個Android開發者都是非常熟悉的,而且很多人也遇到過需要在splash加個廣告圖片,然後延遲3秒在進入主頁面,splash應該只是一個啟動頁面,不應該放廣告,但是那又能怎麼樣呢?又敵不過產品經理。
大多數情況下都會碰到啟動白屏和黑屏的情況,那麼本文將探討幾種我在開發中用到的幾種解決方案。
原理解析
冷啟動
什麼是冷啟動
Android中的冷啟動,使用直白的話就是:
- 當手機重啟後,點選桌面圖示啟動應用的過程就是冷啟動
- 未啟動手機,長時間未使用,應用被kill後,此時點選桌面圖示啟動應用的過程
冷啟動的表現形式
未做處理的情況
- 點選桌面圖示後沒有反應,沒有瞬間開啟應用,也就是沒有馬上看到應用開啟
- 點選桌面圖示後會顯示黑屏 或者 白屏 , 沒有及時渲染出頁面元素
詳情可以檢視下圖:
冷啟動場景演示
從上圖可以看出,點選圖示後出現了短暫的白屏,然後才顯示了 splash 頁面的內容,在splash頁面進行了延遲 1500毫秒再跳轉到主頁面。雖然白屏的時間很短暫,但給使用者的體驗感就不是很好了。
冷啟動產生的原因
冷啟動產生的主要原因要從APP的啟動流程說起:
- 使用者點選 icon
- 系統開始載入和啟動應用
- 應用啟動:開啟空白(黑色)視窗
- 建立應用程序
- 初始化Application
- 啟動 UI 執行緒
- 建立第一個 Activity
- 解析(Inflater)和載入內容檢視
- 佈局(Layout)
- 繪製(Draw)
下圖是啟動的日誌資訊:
[圖片上傳失敗...(image-9f2308-1536935440421)]
APP啟動日誌資訊
從上面可以看出,從應用啟動到佈局和繪製,是需要時間的,這也是無法避免的,越是低端的手機上,這一過程耗費的時間。
解決方案
首先要明確的一點就是:冷啟動無法避免,我們只能去減少冷啟動的時間和適配冷啟動。
如何減少冷啟動的時間?
其實這個問題等同於如何減少應用初始化的時間,從上面的APP啟動流程中,如果我們在應用初始化的操作越多,那麼從初始化到繪製的時間越長,使用者看到真實介面的時間也就越長,可以從如下幾個方面進行:
- 減少在Application中的耗時操作(懶載入)
- 減少在onCreate的耗時操作
如何適配冷啟動?
Android 為我們提供了 android:windowBackground的解決方案,我們可以專門為 SplashActivity設定一個背景來避免 建立空白(黑色) 視窗這一步驟的尷尬,而對於android:windowBackground又延伸了各種各樣的方案。
1. 純色背景 + 啟動圖示
這種做法在國產APP上面少見,在國外的APP常見,簡單的來說就是用 layer-list繪製一個純色的背景加上一個啟動圖示,layer-list 程式碼如下:
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@color/colorPrimary" /> <item> <bitmap android:gravity="center" android:src="@mipmap/ic_launcher" /> </item> </layer-list>
然後我們為SplashActivity建立一個主題:
<resources> <!-- 基本主題 --> <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> </style> <!--純色加啟動圖示的方案--> <style name="SplashThemeLayer" parent="AppTheme"> <item name="windowActionBar">false</item> <item name="windowNoTitle">true</item> <item name="android:windowBackground">@drawable/bg_splash_layer_list</item> </style> </resources>
最後為 SplashActivity設定主題為 SplashThemeLayer 在啟動看看效果吧。
[圖片上傳失敗...(image-82bc0a-1536935440421)]
冷啟動解決方案-純色背景加啟動圖示
是不是實現了想要的效果?點選應用圖示立即顯示了我們的圖示。
關於layer-list我們還可以拓展一下:例如加一個45°的線性漸變.
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item> <shape android:shape="rectangle"> <gradient android:angle="45" android:endColor="@color/colorPrimary" android:startColor="@color/colorAccent" /> </shape> </item> <item> <bitmap android:gravity="center" android:src="@mipmap/ic_launcher" /> </item> </layer-list>
看看效果:
[圖片上傳失敗...(image-945642-1536935440421)]
純色拓展
實現是有點醜,但是哪有怎麼樣呢?[圖片上傳失敗...(image-7164cc-1536935440421)]
2. 使用背景圖片
前面的第一種方式是使用純色背景 + 啟動圖示,這種方式肯定是不滿足我們的產品經理的,他們要的是 個性化 的頁面。
使用背景圖片也是很簡單的,只需要在them將我們之前的drawable替換成我們的圖片即可:
<!--使用圖片的方案--> <style name="SplashThemeImage" parent="AppTheme"> <item name="windowActionBar">false</item> <item name="windowNoTitle">true</item> <item name="android:windowBackground">@mipmap/icon_splish</item> <!--沉浸--> <item name="android:windowTranslucentStatus">true</item> </style>
需要注意的是:Splash頁面的背景顏色需要設定為透明 #00000000,不要設定其他背景,否則會導致圖片的伸縮變形。
看看啟動效果吧:
![[圖片上傳失敗...(image-b368e7-1536935440419)]
從效果圖可以看到,已經得到了我們平常想要的效果了,但是用這種方式又帶了了另外一個問題:
圖片的記憶體佔用和OOM,像這種啟動頁面的,基本上都是直接打包在APP中的,而色彩越是豐富,圖片的體積就越大,大多數情況下我們是無法反駁的,我們可以通過壓縮圖片的方式來儘量減少圖片的體積,這裡推薦一個png壓縮網站:ofollow,noindex">tinypng ,基本上能把我們拿到的設計圖減少一半以上的體積。
3. 說服產品,使用更酷炫的方式來實現吧!
你可以這樣:
[圖片上傳失敗...(image-657fb6-1536935440419)]
center
還可以這樣:
[圖片上傳失敗...(image-2c1331-1536935440419)]
p
由於這不是我做的,所以就不放原始碼了,自己去原作者哪裡看吧
題外:關於熱啟動
什麼是熱啟動
- 使用者按下Home 鍵返回桌面後又馬上點選桌面圖示啟動應用(Application仍然存活)
- 應用未完全被殺死,從啟動列表中進入到應用(Application仍然存活)
熱啟動表現形式
[圖片上傳失敗...(image-382280-1536935440419)]
熱啟動表現顯示
從圖中我們演示了三種操作:
- 點選 Home 鍵返回桌面,點選icon進入應用
- 點選 Home 鍵返回桌面,從任務列表進入應用
- 點選回退鍵退出應用,點選icon進入應用
以上三個操作都是十分的流暢,沒有絲毫的延遲,沒有出現白屏和黑屏的情況。
最後
總結
關於如何進行冷啟動的適配,三種方式,就看個人如何去抉擇了。解決問題的方式有很多,實在不行就解決提出問題的人吧,從根源上解決問題所在。
[圖片上傳失敗...(image-e13aa6-1536935440419)]
無所畏懼
軟
未完待續、敬請期待!
我的部落格地址[圖片上傳失敗...(image-e978fe-1536935440419)]
FullScreenDeveloper