App啟動(dòng)優(yōu)化

1App啟動(dòng)優(yōu)化介紹

背景介紹

第一體驗(yàn) :八秒定律

啟動(dòng)分類

1冷啟動(dòng)
耗時(shí)最多柱徙、衡量標(biāo)準(zhǔn)

1.png

幫助尋找優(yōu)化方向

2熱啟動(dòng)
最快

后臺(tái)--》前臺(tái)

3溫啟動(dòng)
較快

重走LifeCycle 而不會(huì)重走Application荡碾、進(jìn)程等的創(chuàng)建

相關(guān)任務(wù)

冷啟動(dòng)之前:
啟動(dòng)APP
加載空白Window
創(chuàng)建進(jìn)程
隨后任務(wù):
創(chuàng)建Application
啟動(dòng)主線程
創(chuàng)建MainActivity
加載布局
布置屏幕
首幀繪制

優(yōu)化方向

Application和Activity生命周期階段

2App啟動(dòng)時(shí)間測(cè)量方式

adb命令

adb shell am start -W packagename/packagename.首屏Activity
2.png

ThisTime:最后Activity啟動(dòng)耗時(shí)
TotalTime:所有Activity啟動(dòng)耗時(shí)
WaitTime:Ams啟動(dòng)Activity總耗時(shí)

線下方便,不能帶到線上;
非嚴(yán)謹(jǐn)黔夭、精確

手動(dòng)打點(diǎn)

啟動(dòng)時(shí)埋點(diǎn)帽哑,結(jié)束時(shí)埋點(diǎn),二者差值

3.png

開始計(jì)時(shí):
在“attachBaseContext()”里調(diào)用7乇取芦鳍!
結(jié)束計(jì)時(shí):
誤區(qū):onWindowFocusChanged只是首幀時(shí)間,首次繪制
正確:真實(shí)數(shù)據(jù)展示葛账,數(shù)據(jù)資料繪制的第一條展示柠衅。

4.png

精確,可帶到線上籍琳,推薦使用菲宴。
避開誤區(qū),采用第一條數(shù)據(jù)展示
addOnDrawListener要求API16 趋急,替換為addPreDrawListener喝峦。

3App啟動(dòng)優(yōu)化工具選擇

traceview、systrace 兩種方式互相補(bǔ)充

1traceview

圖形的形式展示執(zhí)行時(shí)間宣谈、調(diào)用棧等
信息全面愈犹,包含所有線程
使用方式

//開始
Debug.startMethodTracing("文件名1")
//結(jié)束
Debug.stopMethodTracing()
生成文件在SD卡:Android/data/packagename/files/文件名1.trace

traceview其實(shí)默認(rèn)有一個(gè)最大限制8M,可在方法里參數(shù)指定闻丑。

文件名1.trace 打開

Top Down:
函數(shù)的調(diào)用表漩怎,逐級(jí)調(diào)用

5.png
6.png

cpu真正花在上面的時(shí)間

Call Chart:

7.png

Bottom UP 是Top Down 的反向即誰調(diào)用了我。
另一個(gè)Flame不常用

總結(jié):
運(yùn)行時(shí)開銷嚴(yán)重嗦嗡,整體都會(huì)變慢
可能會(huì)帶偏優(yōu)化方向勋锤。
traceview (可在代碼中埋點(diǎn))

2systrace

結(jié)合Android 內(nèi)核的數(shù)據(jù)生成Html報(bào)告
API18以上,之下推薦TraceCompat

使用方式

8.png

起點(diǎn):

9.png

結(jié)束:


10.png

[圖片上傳中...(12.png-7eb89d-1615694063053-0)]

11.png
12.png
13.png
14.png

總結(jié):
輕量級(jí)侥祭,開銷小 叁执,埋在哪做哪茄厘,TraceView都做
直接反映CPU利用率

CPUtime與walltime區(qū)別:我們要優(yōu)化的是CPUtime,是CPU真正花在上面的時(shí)間

15.png

為什么二者時(shí)間不一樣:鎖沖突谈宛。

4優(yōu)雅獲取耗時(shí)

常規(guī)方式

背景:需要知道啟動(dòng)階段所有方法耗時(shí)
實(shí)現(xiàn):手動(dòng)埋點(diǎn)

16.png
17.png

統(tǒng)計(jì)每個(gè)方法耗時(shí)的話會(huì)非常丑陋次哈,會(huì)導(dǎo)致強(qiáng)耦合。
侵入性強(qiáng)
工作量大

*SystemClock.curretThreadMillis();就是CPU時(shí)間

AOP(Aspect Oriented Programming)面向切面編程 介紹

針對(duì)同一類問題的統(tǒng)一處理:性能問題
無需入侵代碼

AspectJ使用

18.png

AOP相關(guān)知識(shí)點(diǎn)

19.png
20.png
21.png
22.png
23.png

AOP實(shí)戰(zhàn)

24.png
25.png

修改一下代碼:

26.png
27.png

我們沒有在原來代碼上操作吆录,只是加入了一個(gè)類窑滞,非常優(yōu)雅。

無侵入性恢筝;
修改方便哀卫;

5異步優(yōu)化詳解

優(yōu)化技巧

Theme 切換(首屏、閃屏):感官上的快

drawable下創(chuàng)建文件:

28.png
29.png

異步優(yōu)化實(shí)戰(zhàn)

核心思想:子線程分擔(dān)主線程任務(wù)撬槽,并行減少時(shí)間

主線程一個(gè)在工作此改,手機(jī)為多核。有的廠家只分配一個(gè)侄柔。
使用線程池:
啟動(dòng)階段最好不做new線程操作:1粗放共啃;2可能導(dǎo)致內(nèi)存泄漏;3不能復(fù)用

參考AsyncTask獲取CPU數(shù)量
private final int CPU_COUNT=Runtime.getRuntine().availableProcessors();
private final int CORE_POOL_SIZE = Math.max(2,Math.min(CPU_COUNT-1),4);
ExecutorService service =Executors.newFixedThreadPool(CORE_POOL_SIZE );
service.submin(new Runnable(){
  @Override
  public void run(){
    //Bugly
    initBugly();
  }
});
service.submin(new Runnable(){
  @Override
  public void run(){
    //友盟
    initUmeng();
  }
});
....

*可不可以都放在一個(gè)Runnable里呢勋拟?
可以勋磕,但是不好。如果比如new了三個(gè)線程只用了一個(gè)敢靡,等于資源浪費(fèi)挂滓。

*可不可以方法都用子線程呢?
不可以啸胧。
代碼并不滿足異步需求赶站。此部分必須放在 主線程中。
代碼有先后順序的纺念,
解決辦法CountDownLatch:

private  CountDownLatch mCountDownLatch =new CountDownLatch(1);//滿足一次


onCreate(){

  service.submin(new Runnable(){
    @Override
    public void run(){
      //友盟
      initUmeng();
      mCountDownLatch.countDown();//滿足了一次
    }
  });
  .......

  //Create結(jié)束時(shí)調(diào)用
  try{
    mCountDownLatch.await();//檢測(cè)條件贝椿,如果次數(shù)不夠就在此等待
  }catch(InterruptedException e){
    e.printStackTrace();
  }
}
30.png

6異步初始化最優(yōu)解---啟動(dòng)器

常規(guī)異步痛點(diǎn)

31.png

1代碼不優(yōu)雅;
2存在依賴關(guān)系的不好處理陷谱。雖然可以像下面這樣放一起:

32.png

3不方便統(tǒng)計(jì)烙博。維護(hù)成本高。

啟動(dòng)器介紹

核心思想:充分利用CPU多核烟逊,自動(dòng)梳理啟動(dòng)順序渣窜。
1代碼Task化,啟動(dòng)邏輯抽象成Task宪躯。
2根據(jù)所有任務(wù)依賴關(guān)系排序生成一個(gè)有向無環(huán)圖乔宿。
3多線程按照排序后的優(yōu)先級(jí)依次執(zhí)行。

33.png

啟動(dòng)器實(shí)戰(zhàn)

34.png
35.png
36.png
37.png

APP性能優(yōu)化系列-自定義啟動(dòng)器
https://blog.csdn.net/augfun/article/details/109703739?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_baidulandingword-1&spm=1001.2101.3001.4242

7更優(yōu)的初始化延遲方案

常規(guī)方案

New Handler().postDelayed
Feed顯示之后調(diào)用

時(shí)機(jī)不便控制
主線程會(huì)卡访雪,F(xiàn)eed卡頓详瑞,馬上使用的話會(huì)發(fā)現(xiàn)掂林。
不夠優(yōu)雅,可維護(hù)性差

更優(yōu)方案 延遲方案

核心思想坝橡,對(duì)延遲任務(wù)進(jìn)行分批初始化

利用IdleHandler特性泻帮,空閑執(zhí)行

38.png
39.png

8啟動(dòng)優(yōu)化其他方案

優(yōu)化總方針

異步、延遲驳庭、懶加載
技術(shù)刑顺、業(yè)務(wù)相結(jié)合

注意事項(xiàng)

wall time與Cpu time

40.png

監(jiān)控的完善

41.png

收斂啟動(dòng)修改代碼權(quán)限

其他方案

提前加載SharedPreferences:
1Multidex之前加載,利用此階段的CPU饲常。
2復(fù)寫getApplicationContext()返回this

啟動(dòng)階段不啟動(dòng)子進(jìn)程
子進(jìn)程會(huì)共享CPU資源,導(dǎo)致主進(jìn)程CPU緊張
注意啟動(dòng)順序:APP onCreate 之前是ContentProvider

類加載優(yōu)化:提前異步類加載
Class.forName()之家在類本身及其靜態(tài)變量的應(yīng)用類
new 類 可以額外加載類成員變量的引用類

其他

啟動(dòng)階段抑制GC
CPU鎖頻(提一句狼讨,可能導(dǎo)致耗電量增加)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末贝淤,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子政供,更是在濱河造成了極大的恐慌播聪,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件布隔,死亡現(xiàn)場(chǎng)離奇詭異离陶,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)衅檀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門招刨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人哀军,你說我怎么就攤上這事沉眶。” “怎么了杉适?”我有些...
    開封第一講書人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵谎倔,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我猿推,道長(zhǎng)片习,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任蹬叭,我火速辦了婚禮藕咏,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘具垫。我一直安慰自己侈离,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開白布筝蚕。 她就那樣靜靜地躺著卦碾,像睡著了一般铺坞。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上洲胖,一...
    開封第一講書人閱讀 51,679評(píng)論 1 305
  • 那天济榨,我揣著相機(jī)與錄音,去河邊找鬼绿映。 笑死擒滑,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的叉弦。 我是一名探鬼主播丐一,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼淹冰!你這毒婦竟也來了库车?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤樱拴,失蹤者是張志新(化名)和其女友劉穎柠衍,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體晶乔,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡珍坊,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了正罢。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片阵漏。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖腺怯,靈堂內(nèi)的尸體忽然破棺而出袱饭,到底是詐尸還是另有隱情,我是刑警寧澤呛占,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布虑乖,位于F島的核電站,受9級(jí)特大地震影響晾虑,放射性物質(zhì)發(fā)生泄漏疹味。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一帜篇、第九天 我趴在偏房一處隱蔽的房頂上張望糙捺。 院中可真熱鬧,春花似錦笙隙、人聲如沸洪灯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽签钩。三九已至掏呼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間铅檩,已是汗流浹背憎夷。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留昧旨,地道東北人拾给。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像兔沃,于是被迫代替她去往敵國(guó)和親蒋得。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 0 紙上談兵——App啟動(dòng)優(yōu)化 紙上談兵系列是我在學(xué)習(xí)App性能優(yōu)化的筆記粘拾,紙上談兵這個(gè)名字就很好的反應(yīng)了這次只是...
    nick_young閱讀 1,457評(píng)論 0 2
  • anr文件路徑 /data/anr/traces.txt 啟動(dòng)優(yōu)化工具 traceview: Debug.star...
    7i昂閱讀 331評(píng)論 0 0
  • 用戶希望應(yīng)用能夠及時(shí)響應(yīng)并快速加載窄锅。啟動(dòng)時(shí)間過長(zhǎng)的應(yīng)用可能會(huì)導(dǎo)致用戶在對(duì)應(yīng)用給出很低的評(píng)分,甚至完全棄用缰雇。 啟動(dòng)狀...
    zcwfeng閱讀 3,019評(píng)論 1 28
  • APP性能優(yōu)化已成為衡量中高級(jí)Android開發(fā)程序員的標(biāo)準(zhǔn)之一,所以想要突破職業(yè)瓶頸追驴,掌握一些必要的優(yōu)化技巧就很...
    aitality閱讀 549評(píng)論 0 1
  • 夜鶯2517閱讀 127,720評(píng)論 1 9