啟動優(yōu)化可以整體分為兩個階段和兩個間隙:
兩個階段:Application階段和Activity階段
兩個間隙:handle message 間隙和數(shù)據(jù)加載間隙
Application階段
App進程由zygote進程fork出來之后調(diào)用ActivityThread的main方法,觸發(fā)bindApplication方法,這是Application階段的開始。
然后調(diào)用attchBaseContext,在這個階段,針對低端機具有較長的MultiDex耗時做針對性優(yōu)化。參考“抖音 BoostMultiDex 優(yōu)化實踐”。
installProvider階段:在這個階段可以做第三方SDK的初始化。具體可以參考LeakCanary的使用。
onCreate階段:這里有很多三方庫和業(yè)務(wù)的初始化操作,是通過異步、按需、預加載等手段做優(yōu)化的主要時機,它也是 Application 階段的末尾。(App StartUp的使用)
Activity階段
首先經(jīng)歷的是其onCreate生命周期,這里涵蓋了首屏業(yè)務(wù)優(yōu)化的主要場景也是開啟異步并發(fā)的主要時機,在其中有個重要的 setContentView 方法會觸發(fā) DecorView 的 install,可嘗試對 DecorView 的構(gòu)建進行預加載;后續(xù)自然來到View 構(gòu)建的階段,可采用異步 Inflate 配合 X2C(編譯期將 xml 布局轉(zhuǎn)代碼)以及AsyncLayoutInflater異步加載布局,并提升相應(yīng)異步線程優(yōu)先級的方法綜合優(yōu)化;再來到View 的整體渲染階段,涵蓋 measure、layout、draw 三部分,這里可嘗試從層級、布局、渲染上取得優(yōu)化收益。比如減少層級數(shù),勇stub和merge等等。
最后是首屏數(shù)據(jù)加載階段,這部分涵蓋非常多數(shù)據(jù)相關(guān)的操作,也需要綜合性優(yōu)化,可嘗試預加載、緩存或網(wǎng)絡(luò)優(yōu)先級調(diào)度等手段。例如對于不要立即加載的數(shù)據(jù)采用IdleHandler進行延后處理。
啟動耗時成因
系統(tǒng)資源類型劃分出五大成因,分別是:CPU Time、CPU Schedule、IO Wait、Lock Wait 和 IPC
CPU Time:
1、反射:反射的耗時主要是字符串去查找 Method 或者 Field,這個優(yōu)化策略也可以考慮提前查找 Method 和 Field 緩存起來。像EventbUS里面就用了大量的反射,采用APT的方式在編譯期生成對應(yīng)的文件,從而減少反射的使用。
2.類加載,類的加載過程包括:Load,從 Dex 文件里讀取類的信息,可通過類重排優(yōu)化;Verify,驗證指令是否合法等,通過關(guān)掉 Class Verify 可以優(yōu)化該過程,同時高版本的 vdex 也是為了優(yōu)化 verify 過程而設(shè)計,在 dex2oat 的時候做 verify,verify 之后的結(jié)果保存成 vdex,后續(xù)只需要加載 vdex;Link,給 Field、Method 分配內(nèi)存,按照名字排序以方便后續(xù)反射的時候查找 Field、Method 等,這個過程的優(yōu)化,art 虛擬機采用了 ImageSpace 的方案進行了優(yōu)化,將 Link 后的內(nèi)存保存為 image 文件,后續(xù)可以直接 load 這個 image 文件,省去了 Link 過程;Init,類的初始化。
常用工具
TraceView、Systrace、Android Profiler