Android APP 啓動速度優化

啓動過程產品邏輯

 

從用戶點擊桌面圖標到首頁完全加載,需要經過三個頁面,第三步中,如果用戶是安裝或升級後第一次打開應用,則顯示引導頁,否則顯示廣告頁。

透明頁

點擊應用圖標後系統會有3秒的響應時間,這段時間系統好像無響應,實則在爲應用準備運行環境,打開一個無邊框的窗口,這個窗口默認爲白色,現在App調整成了透明,然後會初始化各個三方庫,向網絡請求應用圖標序號。

閃屏頁

 

閃屏頁是啓動過程中最爲複雜的一步,它包含:檢查權限並彈窗提醒,提前請求首頁數據,啓動引導頁或廣告頁

檢查權限

進入閃屏頁,首先會按順序檢查四個權限,分別是讀寫手機文件的權限、獲取本機號碼本機唯一標識碼的權限、手機錄音的權限、獲取手機定位的權限。如果其中一個對話框拒絕授權,會再彈出一個對話框勸用戶授權,如果還不授權則退出APP。詳細邏輯如圖。

請求首頁數據

如果請求成功會緩存請求結果,如果請求失敗會取上次緩存的請求結果

啓動引導頁或者廣告頁

在啓動引導頁或廣告頁之前,會先停頓2秒,然後根據是否是第一次進入應用決定是進引導頁還是廣告頁

引導頁

 

如上圖所示,引導頁需要向右劃4下,並點擊立即體驗進入應用

廣告頁

安裝後第二次打開應用會顯示廣告頁,廣告頁會根據上一次拉取的圖片進行顯示

首頁

           

啓動過程代碼邏輯

App

這裏是整個應用的入口類,在這個對象創建時,會初始化SmartRefreshLayout下拉刷新組件,然後會在onCreate生命週期回調方法中執行如左圖邏輯,大部分是初始化業務SDK

 

上圖是App類中的全局字段和全局方法

ChangeIconActivity

 

WelcomeActivity

 

其中SP是手機存儲中的SharedPreference XML文件

AdvertNewActivity

 

GuideActivity

 

啓動原理

 

 

  • 應用的啓動分爲兩部分工作,第一部分工作由Android操作系統完成,包括以下三項:
  1. 加載並啓動應用程序
  2. 爲即將啓動的APP顯示一個空白窗口
  3. 創建應用進程
  • 第二部分有APP的進程自己完成,包括以下六項任務:
  1. 創建應用進程底層對象
  2. 啓動JVM主線程
  3. 創建應用入口Activity對象
  4. 將XML中的文本轉化爲可運行的View對象
  5. 佈局各個控件
  6. 實際繪製各個控件

當入口頁面第一幀繪製完畢,操作系統就會把繪製好的畫面切換進屏幕的最上層,然後用戶就可以開始與APP交互。

從進程角度分析,應用的啓動涉及四個進程,分別是Launcher進程(實際就是系統桌面APP),system_server進程(承載了大部分的系統服務功能),Zygote進程(用於創建新進程),App進程。

當用戶點擊桌面圖標,實際是點擊Launcher應用上的帶圖標的按鈕,觸發啓動。

從類和方法調用角度分析如下圖所示:

 

圖中長方形代表類,線上的文字代表函數調用,序號代表調用順序,其中可以直接優化的就是Application類的OnCreate方法(如圖中序號5位置)和Activity的onCreate方法如圖中序號9的位置。

優化措施

啓動窗口背景優化

如啓動原理部分介紹,系統在啓動APP進程前會先打開一個空白窗口,之前APP已將此窗口設置爲透明,但爲了給用戶更快的響應速度和更好的啓動體驗,可以將此窗口設置爲與啓動頁同一張圖片,這樣由這個窗口到啓動頁雖然是兩個頁面,但是顯示一張圖,用戶是感知不到切換的。具體做法見這裏的啓動主題優化部分。

參考案例:百度地圖Android APP。

Application類的優化

可以將APP啓動過程中的retrofit,友盟,市民卡web容器(含x5內核),通付盾,無痕埋點的初始化過程放在子線程中進行。還可以優化精簡邏輯。

閃屏頁優化

(1)Activity合併,是否可以把換圖標的ChangeIconActivity的邏輯、廣告頁AdvertNewActivity的邏輯、引導頁GuideActivity的邏輯合併進閃屏頁的WelcomeActivity的邏輯,從而減少Activity切換的時間開銷。

(2)網絡請求優化,是否可以把部分啓動過程中的網絡請求放在首頁

(3)閃屏頁在跳轉引導頁或廣告頁之前會故意停留2s多,可以看是否可以去掉,如不可以去掉,也可以動態計算停留時長,就是把停留時長減去之前啓動邏輯(包括網絡請求返回數據)的時長

引導頁放在首頁上

如上圖所示,示例APP:抖音:

閃屏頁申請權限的對話框放在首頁進行

這樣用戶可以在前臺處理授權對話框,首頁在後邊可以同時處理大量的網絡訪問和頁面邏輯,兩邊同時進行。示例APP:抖音

監控措施

adb命令

adb shell am start -S -R 10 -W com.hfi.hangzhoubanshi/ .home.activity.ChangeIconActivity  

其中-S表示每次啓動前先強行停止,-R表示重複測試次數。每一次的輸出如下所示信息:

Stopping: com.example.app  
Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.example.app/.MainActivity }  
Status: ok  
Activity: com.example.app/.MainActivity  
ThisTime: 1059  
TotalTime: 1059  
WaitTime: 1073  
Complete  

其中TotalTime代表當前Activity啓動時間,將多次TotalTime加起來求平均即可得到啓動這個Activity的時間。

缺點:應用的啓動過程往往不只一個Activity,有可能是先進入一個啓動頁,然後再從啓動頁打開真正的首頁。某些情況下還有可能中間經過更多的Activity,這個時候需要將多個Activity的時間加起來。

將多個Activity啓動時間加起來並不完全等於用戶感知的啓動時間。例如在啓動頁可能是先等待某些初始化完成或者某些動畫播放完畢後再進入首頁。使用命令行統計的方式只是計算了Activity的啓動以及初始化時間,並不能體現這種等待任務的時間。

沒有在AndroidManifest.xml對應的Activity聲明中指定<intent-filter>或者屬性沒有android:exported="true"的Activity不能使用這種命令行的形式計算啓動時間。

logcat日誌

根據系統日誌來統計啓動耗時,在Android Studio中查找已用時間,必須在logcat視圖中禁用過濾器(No Filters)。因爲這個是系統的日誌輸出,而不是應用程序的。你也可以查看其它應用程序的啓動耗時。

過濾displayed輸出的啓動日誌.

 

但是這種方法只能統計Activity的從觸發到完全顯示的時間,但是沒有包含網絡訪問、故意停留和用戶操作的時間,所以也不能準確的反映啓動時間。

其他統計

Testin雲測的啓動時間並不準確,大部分在1s以內,顯然不可能。網易雲筆記推薦的NimbleAPP已變成付費服務,且價格需要商談,所以也不推薦。友盟上未找到關於APP啓動時間的字段。

自定義統計時間

在APP的attachBaseContext()的最後加入

val sp:SharedPreferences = getSharedPreferences("sp_hzgovernment", Context.MODE_PRIVATE)  
sp.edit().putLong("application_attach_time", System.currentTimeMillis()).apply()  

然後在MainActivity的onCreate()前邊添加如下代碼

var appAttachTime = SPUtils.getLong("application_attach_time", 0);  
var diffTime = System.currentTimeMillis() - appAttachTime;//從application到入口Acitity的時間  
Log.i("Total Time", diffTime.toString() + "ms")  

就可以統計出從App啓動,到首頁開始加載的時長

針對目前APP的優化目標

現在的啓動時長

 

第一次啓動

第二次啓動

小米MIX2S

14.6s

8.3s

華爲榮耀7X

20.7s

9.3s

OPPO A37f

14.2s

9.8s

第一次啓動指首次安裝後的打開應用,包括授權和引導頁的操作時間

第二次啓動指打開過一次後的再次啓動,不包括授權,廣告頁不點跳過

誤差:操作系統工作時長並未計算在內,因此實際啓動比上面的時間長1到2秒

啓動時長分析

以小米MIX2S爲準

第一次啓動

點擊桌面圖標

空窗口

閃屏頁啓動

授予權限

閃屏頁停留

引導頁啓動

引導頁操作

跳轉主頁

開始

啓動時長------》

結束

 

約2s

1.1s

4s

2.2s

0.3s

2s

 

第二次啓動

點擊桌面圖標

空窗口

閃屏頁啓動

閃屏頁停留

廣告頁啓動

廣告頁停留

跳轉主頁

開始

啓動時長-------》

結束

 

約2s

1.1s

2.2s

0.2s

4s

 

優化目標

點擊圖標後有更快響應

用戶體驗到的啓動速度有明顯提升(首次啓動時間提高30%以上,第二次啓動時間提高20%以上)

參考引文

1.《Android 性能優化(一) —— 啓動優化提升60%》

2.《android app的啓動流程》

3.《App startup time》

4.《如何統計Android App啓動時間》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章