Android 你應該知道的的應用冷啟動過程分析和優化方案
你有沒有發現,點選安卓手機桌面上的App圖示時,有時候應用馬上進入主介面,有時候要經歷好幾秒甚至更久的白屏(也可能是黑屏)時間才能進入主介面呢?這其實是安卓應用常見的冷熱啟動問題。本文就和大家一起聊聊冷熱啟動方式和啟動頁的體驗優化方案。
啟動方式
安卓應用的啟動方式分為三種:冷啟動、暖啟動、熱啟動,不同的啟動方式決定了應用UI對使用者可見所需要花費的時間長短。顧名思義,冷啟動消耗的時間最長。基於冷啟動方式的優化工作也是最考驗產品使用者體驗的地方。談及優化之前,我們先看看這三種啟動方式的應用場景,以及啟動過程中系統都做了些什麼工作。
冷啟動 (Cold start)
在安卓系統中,系統為每個執行的應用至少分配一個程序 (多程序應用申請多個程序) 。從程序角度上講,冷啟動就是在啟動應用前,系統中沒有該應用的人和程序資訊 (包括 Activity、Service 等) 。所以,冷啟動產生的場景就很容易理解了,比如裝置開機後應用的第一次啟動,系統殺掉應用程序 (如:系統記憶體吃緊引發的 kill 和 使用者主動產生的 kill) 後 的再次啟動等。那麼自然這種方式下,應用的啟動時間最長,因為相比另外兩種啟動方式,系統和我們的應用要做的工作最多。
應用發生冷啟動時,系統有三件任務要做:
開始載入並啟動應用;
應用啟動後,顯示一個空白的啟動視窗;
建立應用程序資訊;
系統建立應用程序後,應用就要做下面這些事情:
初始化應用中的物件 (比如 Application 中的工作);
啟動主執行緒 (UI 執行緒) ;
建立第一個 Activity;
載入內容檢視 (Inflating) ;
計算檢視在螢幕上的位置排版 (Laying out);
繪製檢視 (draw)。
只有當應用完成第一次繪製,系統當前展示的空白背景才會消失,才會被 Activity 的內容檢視替換掉。也就是這個時候,使用者才能和我們的應用開始互動。下圖展示了冷啟動過程系統和應用的一個工作時間流:
這其中有兩個 creation 工作,分別為 Application 和 Activity creation。從圖中看出,他們均在 View 繪製展示之前。所以,在應用自定義的 Application 類和 第一個 Activity 類中,onCreate() 方法做的事情越多,冷啟動消耗的時間越長。
暖啟動 (Warm start)
當應用中的 Activities 被銷燬,但在記憶體中常駐時,應用的啟動方式就會變為暖啟動。相比冷啟動,暖啟動過程減少了物件初始化、佈局載入等工作,啟動時間更短。但啟動時,系統依然會展示一個空白背景,直到第一個 Activity 的內容呈現為止。
熱啟動 (Lukewarm start)
相比暖啟動,熱啟動時應用做的工作更少,啟動時間更短。熱啟動產生的場景很多,常見如:使用者使用返回鍵退出應用,然後馬上又重新啟動應用。
啟動時間
從 Android 4.4 (API 19) 開始,Logcat 自動幫我們打印出應用的啟動時間。這個時間值從應用啟動 (建立程序) 開始計算,到完成檢視的第一次繪製 (即 Activity 內容對使用者可見) 為止。如:
11-15 14:06:25.710 1071-1130/? I/ActivityManager: Displayed com.yifeng.qqtemp/.MainActivity: +3s610ms
對應在 logcat 視窗上的顯示如圖 (記得修改過濾條件) :
對於使用者來講,看不到具體的啟動時間,而是應用啟動時白屏展示的體驗問題。舉個例子來對比一下冷熱啟動的實際啟動情況。新建一個工程,為了更好地模擬演示冷熱啟動效果,這裡我在自定義 Application 類的 onCreate 方法中添加了如下程式碼來延長應用的冷啟動時間:
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
然後第一次編譯執行,應用採取冷啟動的方式開啟 (使用選單鍵關閉最近開啟的應用,也能達到促使應用使用冷啟動方式,延長啟動時間的效果) ;接著使用返回鍵退出應用,再點選桌面應用圖示,應用將採用熱啟動的方式開啟。整個操作流程對應的效果如圖:
可以看到,冷啟動方式下,應用要經歷一個短暫的白屏時間 (這個時間的長短視具體情況而定),使用者體驗極其不好。相比而言,熱啟動方式下,使用者可以較快進入 Activity 主介面與應用發生互動行為。
優化方案
應用的冷啟動總是無法避免的,也就是說冷啟動時使用者總要經歷一個啟動等待時間。開發人員唯一能做的就是在 Application 和 第一個 Activity 中,減少 onCreate() 方法的工作量,從而縮短冷啟動的時間。像應用中嵌入的一些第三方 SDK,都建議在 Application 中做一些初始化工作,開發人員不妨採取懶載入的形式移除這部分程式碼,而在真正需要用到第三方 SDK 時再進行初始化。
還有一種簡單粗暴的方式就是通過主題設定,不顯示啟動時的白屏背景。新建一個主題樣式,並新增如下屬性:
<style name="LaunchStyle" parent="AppTheme">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowNoTitle">true</item>
</style>
或
<item name="android:windowDisablePreview">true</item>
然後將這個主題樣式設定給第一個啟動的 Activity ,如:
<activity
android:name=".MainActivity"
android:theme="@style/LaunchStyle">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
備註:這裡沒有將該主題設定在 Application 標籤裡,主要是該主題只適用於第一個 Activity,如果放置在 Application 標籤中會修改所有 Activity 的主題樣式。
再修改該 Activity 類的程式碼,在載入佈局檢視前,將主題修改回來:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTheme(R.style.AppTheme);
setContentView(R.layout.activity_main);
}
這麼設定之後,效果如圖:
可以看到,冷啟動方式下,使用者點選桌面圖示,沒有任何反應,過一段時間應用才打開。其實這裡只是將白屏背景透明化或者隱藏起來而已。
很顯然,這種處理方式使用者體驗也極差。不過可喜的是,我們可以通過主題中的 windowBackground 屬性,自定義應用啟動時的視窗背景。至於這個背景如何設計,Google 已經在官網上給了建議和規範,可以參考:Launch screens(需要翻牆)。其實就是兩種樣式,如圖:
左圖採用應用的 Logo 和 Slogan (甚至為了簡單,Slogan 都可以不要),可以增強品牌推廣效應;右圖利用了 placeholder ,與主介面的 UI 框架保持一致,給使用者產生一種應用啟動非常快的視覺感受。這兩種方案各自目的和應用場景有所不同,但設計理念確實不錯。下面我們一一模仿實現,先看第一種。
新建一個名為 shape_launch.xml 的 drawable 檔案,內容如下:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
android:opacity="opaque">
<item android:drawable="@color/colorPrimary"/>
<item >
<bitmap
android:src="@mipmap/ic_launcher"
android:gravity="center" />
</item>
</layer-list>
然後修改 styles.xml 檔案中的主題樣式:
<style name="LaunchStyle" parent="AppTheme">
<item name="android:windowBackground">@drawable/shape_launch</item>
</style>
最後將這個主題設定給啟動的 Activity,設定過程和上面隱藏啟動視窗時的設定一樣。效果如圖:
第二種,使用與主介面 UI 框架一致的 placeholder 內容,這種情況下需要計算諸如 Statusbar、Toolbar 控制元件的高度,shape_launch.xml 內容如下:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
android:opacity="opaque">
<item android:drawable="@color/colorPrimaryDark"/>
<item
android:drawable="@color/colorPrimary"
android:top="25dp"/>
<item
android:top="81dp"
android:drawable="@android:color/white">
</item>
</layer-list>
這裡模擬了一個高度為25dp的狀態列和一個高度為56dp的標題欄,給使用者一種錯覺:點選桌面圖示,應用立即啟動並進入主介面。效果如圖:
以上兩種方式是按照 Google 的建議實現的 UI 效果,當然你還可以有更好的設計方式,只要能夠解決冷啟動帶來的白屏過渡問題,都能帶來不錯的使用者體驗。比如你還可以適度結合 Activity 內容檢視使用動畫過渡效果,比如:
或者這樣
參考連結
相關推薦
Android 你應該知道的的應用冷啟動過程分析和優化方案
你有沒有發現,點選安卓手機桌面上的App圖示時,有時候應用馬上進入主介面,有時候要經歷好幾秒甚至更久的白屏(也可能是黑屏)時間才能進入主介面呢?這其實是安卓應用常見的冷熱啟動問題。本文就和大家一起聊聊冷熱啟動方式和啟動頁的體驗優化方案。 啟動方式
Android應用冷啟動過程分析和優化方案你瞭解多少
你有沒有發現,點選安卓手機桌面上的App圖示時,有時候應用馬上進入主介面,有時候要經歷好幾秒甚至更久的白屏(也可能是黑屏)時間才能進入主介面呢?這其實是安卓應用常見的冷熱啟動問題。本文就和大家一起聊聊冷熱啟動方式和啟動頁的體驗優化方案。 啟動方式 安卓應用的啟動方式分為三種:冷啟動
android應用冷啟動過程分析與優化過程
http://yifeng.studio/2016/11/15/android-optimize-for-cold-start/?utm_source=tuicool&utm_medium=referral 你有沒有發現,點選安卓手機桌面上的App圖示時,有時候應用馬上進入主介面,有時候要經歷好幾秒甚
Android中APP應用冷啟動黑白屏原因 優化解決方案
冷啟動 前言 應用啟動 冷啟動流程 問題原因 解決方法 優化 前言 做過APP開發,尤其是複雜專案的同學應該會經歷過APP在桌面點選冷啟動的時候,你以為會順利開啟應用首頁,但是出現在你眼前的
Android 7.0應用冷啟動流程分析
最近在為自己Moto G定製Rom,順便重新讀了一遍Android 7.0的相關原始碼,特此記錄當做筆記. 在開始正文之前,首先要明白冷啟動和熱啟動.所謂冷啟動就是啟動該應用時,後臺沒有該應用的程序,此時系統會建立一個程序分配給它(AMS通過Socket和Zy
android原始碼4.4.2----系統啟動過程分析
public class SystemServer { private static final String TAG = "SystemServer"; public static final int FACTORY_TEST_OFF = 0; public static final int F
第一次使用Android Studio時你應該知道的一切配置
出現 jpg rcu true 導入 職位 文章 加載 什麽 【聲明】 歡迎轉載,但請保留文章原始出處→_→ 生命壹號:http://www.cnblogs.com/smyhvae/ 文章來源:http://www.cnblogs.com/smyhvae/p/43909
第一次使用Android Studio時你應該知道的一切配置(二):新建一個屬於自己的工程並安裝Genymotion模擬器
人性 pro net 參考 json irb 一個地方 vid 調試 【聲明】 歡迎轉載,但請保留文章原始出處→_→ 生命壹號:http://www.cnblogs.com/smyhvae/ 文章來源:http://www.cnblogs.com/smyhvae/p/439
Android中關於View滑動的實現你應該知道的
nan ida gif 當前位置 距離 保存 改變 post 控件 滑動作為Android中最基礎的特效之一,使用場景非常廣泛。實現的方式也有多種,理解各種滑動的實現方式。清楚在開發中根據自己的實際需求,選擇合理的實現方案。這篇文章從:scrollTo()/scrollBy
第一次使用Android Studio時你應該知道的一切配置(三):gradle項目構建
gen 官方 配置文件 conf 什麽 學習 package ack 處的 ?【聲明】 歡迎轉載,但請保留文章原始出處→_→ 生命壹號:http://www.cnblogs.com/smyhvae/ 文章來源:http://www.cnblogs.com/smyhvae
Android進階(二): 應用程序啟動過程
1.前言 最近一直在看 《Android進階解密》 的一本書,這本書編寫邏輯、流程都非常好,而且很容易看懂,非常推薦大家去看看(沒有收廣告費,單純覺得作者寫的很好)。 今天就將 應用程序啟動過程 總結一下(基於Android 8.0 系統)。 文章中例項&nbs
Android Fragment 你應該知道的一切
很久以前寫過兩篇Fragment的介紹,主要就是介紹其功能:Android Fragment 真正的完全解析(上)和Android Fragment 真正的完全解析(下) 有興趣的可以湊合看下。之前的部落格屬於怎麼使用Fragment,本文目標教你如何用好Fragment,即
Android應用程式啟動過程原始碼分析(2)
Step 9. ActivityStack.startActivityUncheckedLocked 這個函式定義在frameworks/base/services/java/com/android/server/am/ActivityStack.java檔案中: view plain pu
Android材料設計庫之摺疊式佈局你應該知道的一切
github原始碼地址:https://github.com/geduo83/AndroidMaterialDesign/tree/master/module_drawerlayout_coordinatorlayout 在Android5.0之後,Android給我們提供了非常豐富關於UI
Android應用程式啟動過程原始碼分析
前文簡要介紹了Android應用程式的Activity的啟動過程。在Android系統中,應用程式是由Activity組成的,因此,應用程式的啟動過程實際上就是應用程式中的預設Activity的啟動過程,本文將詳細分析應用程式框架層的原始碼,瞭解Android
Activity生命週期的回撥,你應該知道得更多!--Android原始碼剖析(上)
private class ApplicationThread extends ApplicationThreadNative { //... public final void schedulePauseActivity(IBinder token, boolean finished,
Android應用程式啟動過程
// --runtime-init, --setuid=, --setgid=, // and --setgroups= must go first argsForZygote.add("--runtime-init"); argsFor
Android APK打包安裝、應用程序啟動過程、Activity啟動流程
目錄 一、Android APK的構建過程 通過IDE可以生成可以在android裝置中安裝的apk檔案,Google官方提供的構建APK的過程流程圖如下: 打包APK流程總結如下: AAPT(Android Asset Packaging Tool)工
關於Android記憶體優化你應該知道的一切
介紹 在Android系統中,記憶體分配與釋放分配在一定程度上會影響App效能的—鑑於其使用的是類似於Java的GC回收機制,因此係統會以消耗一定的效率為代價,進行垃圾回收。 在中國有句老話:”由儉入奢易,由奢返儉難”。而此諺語也似乎正適應於Android的
Android應用冷啟動解析和優化方案
前言 在我們點選Android手機桌面APP圖示時,有時候我麼會發現,應用並不是直接進入閃屏頁或者應用主頁面,而是會有一個短暫時間的白屏才能進去。但如果我們點選Back鍵退出應用,在點選返回的時候卻沒有白屏或者白屏時間幾乎不可見。為什麼會出現這種情況呢?這就涉及到Andro