1. 程式人生 > 其它 >大廠Android啟動優化-出其不意的優化手段

大廠Android啟動優化-出其不意的優化手段

常規的手段優化後,我們能解決基本的問題,但是我們得繼續追求極致,本章將分享一些意想不到的手段。

1 首頁合併

通常我們啟動的時候分為閃屏和首頁兩個頁面,我們將閃屏和首頁合併成一個,通過fragment來操作真實頁面,廣告設計成一個dialog fragment浮在首頁就行。基本的收益在100ms左右。 首頁合併後發現幾個問題:首頁管理、喚端啟動問題。

  • 首頁無法使用singletask,singletask的問題我們通過手動維護一個activity棧去管理,保證一個首頁。
  • 喚端啟動,第三方app喚端沒有加newtask標籤,導致頁面啟動在第三方app內,這個暫時沒有遇到很好的解決方式,還是在推動比較大的第三方平臺去解決。

2 渲染訊息優先順序佇列

我們資料請求後,通過handler將訊息傳送到主執行緒,handler訊息佇列內可能比較繁忙,我們思考的是將資料回撥和圖片回撥的訊息傳送到訊息佇列前面。
MessageQueue其實提供了一個方法handler.sendMessageAtFrontOfQueue的方式。

3 dex2oat

Android ART虛擬機器後,可以將dex檔案預先的翻譯處理成機器碼直接執行,在Android 5 - 7版本,dex處理是在app安裝的時候處理的,但是由於dex2oat效能影響較大,安裝的時候將耗時過長,Android 7後改為安裝的時候不做翻譯,執行時還是解釋執行,執行時的時候記錄執行的函式等資訊,在手機閒置的情況下去把這些熱方法做dex2oat,下次執行直接執行機器碼。
但是系統判斷閒置的條件比較苛刻,導致大部分情況下app沒有被dex2oat,另外網際網路app快速發展,發版速度較快,所以dex2oat的利用率低,通過app自己手動呼叫系統dex2oat達到快速將app的dex轉化,提高程式碼執行效率,該方案的收益大概在10%。相關的詳細知識可以網上搜索一下。

系統記錄熱方法的資料檔案存在 /data/misc/profiles/cur/0/packageName/primary.prof下,我們可以通過FileObserver監聽這個這個檔案修改判斷是否需要dex2oat。
dex2oat可以通過shell命令執行cmd package compile -m speed-profile -f packageName

4 Redex

Linux 檔案系統從磁碟讀檔案的時候,會以 block 為單位去磁碟讀取,一般 block 大小是 4KB。也就是說一次磁碟讀寫大小至少是 4KB,然後會把 4KB 資料放到頁快取 Page Cache 中。如果下次讀取檔案資料已經在頁快取中,那就不會發生真實的磁碟 I/O,而是直接從頁快取中讀取,大大提升了讀的速度。所以上面的例子,我們雖然讀了 1000 次,但事實上只會發生一次磁碟 I/O,其他的資料都會在頁快取中得到。

Dex 檔案用的到的類和安裝包 APK 裡面各種資原始檔一般都比較小,但是讀取非常頻繁。我們可以利用系統這個機制將它們按照讀取順序重新排列,減少真實的磁碟 I/O 次數。

類重排

啟動過程類載入順序可以通過插裝靜態程式碼塊獲取。

class A {
    static {
        //記錄
    }
}

然後通過 ReDex 的Interdex調整類在 Dex 中的排列順序,最後可以利用 010 Editor 檢視修改後的效果。

從多方拿到的資料來看,收益在0-6%,整體不是很明顯,而且需要把redex工程化、考慮和proguard的相容等問題。

5 黑科技

微信Hardcoder

構建了App與系統(ROM)之間可靠的通訊框架,讓系統知道App的需求,可以讓app獲取更多的系統資源。

原理

  • 1、其實質是讓App跨過Framework直接跟廠商ROM通訊
  • 2、分為Client端和Server端,Server端由廠商系統側自行實現
  • 3、它們直接採用 LocalSocket 方式,Hardcoder是 Native 實現的,使用了Linux的Socket介面實現了一套自己的LocalSocket。

整體收益不是特別明顯。

GC抑制

網上講的很多文章都是4.4版本的GC抑制,因為在ART虛擬機器之前,Android的GC回收演算法是停止一切,所有抑制GC收益很大。

ART虛擬機器後,採用並行回收的演算法,GC回收對效能的影響大大降低。但是通過systrace分析,在啟動過程中,GC執行緒也存在搶佔系統資源的情況。

Google 也注意到了後臺 GC 對於應用啟動速度的影響,並嘗試了在 Android 中對這一場景進行優化。在 Android 10 的程式碼中。有如下提交:cs.android.com/android/_/a…

這個改動的邏輯是:應用啟動時 Zygote Fork 出新的程序之後,在2秒內暫時提高 Background GC 任務觸發的閾值。這樣 Background GC 將會更難被觸發。

那麼 Google 這個提交的優化效果如何?Comments 中包含了測試效果,可以看到各個應用的啟動速度都有提升。

可以看出抑制 GC 有較明顯的效果,但是 Google 這個改動只存在於 Android 10 及以上的機型。那麼可以找找方法在 Android 10 之前的機器也享受到這個優化的效果。

6 Hook框架

開源框架 epic
利用hook框架發現問題,比如監控大io讀取,獲取系統服務等。

7 主執行緒優先順序問題

Android的離奇陷阱 — 設定執行緒優先順序導致的微信卡頓慘案
在Anroid11以下,線上程沒有start完成設定執行緒優先順序可能導致修改的是主執行緒優先順序,導致主執行緒優先順序降低,影響執行效率。

8 後繼

至此,相關的優化內容已經完成,接下來分享怎麼保持我們的優化成果和快速發現問題。

文章轉自 https://juejin.cn/post/7017340559752691743 如有侵權,請聯絡刪除。

相關視訊推薦:

【2021最新版】Android studio安裝教程+Android(安卓)零基礎教程視訊(適合Android 0基礎,Android初學入門)含音視訊_嗶哩嗶哩_bilibili

【 Android進階教程】——App啟動速度的優化_嗶哩嗶哩_bilibili

Android進階系統學習——高階UI卡頓效能優化_嗶哩嗶哩_bilibili