一. Android 啟動(dòng)時(shí)間優(yōu)化

系統(tǒng)啟動(dòng)過程:
1)開機(jī)打開電源
2)BootLoader程序
3)Linux的 init.rc

  1. init進(jìn)程
    5)Zygote的JVM
    6)SystemServer進(jìn)程
    Binder線程池
    SystemServiceManager(AMS桥氏、WMS、PMS择浊、CameraService等等被啟動(dòng))

1)啟動(dòng)頁白屏及黑屏解決?
2)啟動(dòng)太慢怎么解決媒至?
3)怎么保證應(yīng)用啟動(dòng)不卡頓齿坷?
4)App啟動(dòng)崩潰異常捕捉
5)統(tǒng)計(jì)啟動(dòng)時(shí)長(zhǎng),標(biāo)準(zhǔn)

App啟動(dòng)速度是用戶的第一印象,本章會(huì)介紹精準(zhǔn)度量啟動(dòng)速度的方式五垮,啟動(dòng)優(yōu)化的相關(guān)工具睬棚、常規(guī)優(yōu)化手段等第煮,同時(shí)我會(huì)介紹異步初始化以及延遲初始化的最優(yōu)解,以最優(yōu)雅抑党、可維護(hù)性高的的方式獲得閃電般的啟動(dòng)速度包警。...

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

App Startup time
冷啟動(dòng):耗時(shí)最多、衡量標(biāo)準(zhǔn)底靠。
啟動(dòng)App害晦、加載空白Window、創(chuàng)建進(jìn)程
隨后任務(wù)苛骨,創(chuàng)建Application篱瞎、啟動(dòng)主線程、創(chuàng)建MainActivity痒芝。

熱啟動(dòng):后臺(tái) ——> 前臺(tái)俐筋。最快
溫啟動(dòng):較快。僅僅重走LifeCycle严衬。

優(yōu)化方向:
Application和Activity生命周期

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

兩種方式:adb 命令 / 手動(dòng)打點(diǎn)

  1. adb方式
    adb shell am start -W packagename/首屏Activity
    ThisTime:最后一個(gè)Activity啟動(dòng)耗時(shí)
    TotalTime:所有Activity啟動(dòng)耗時(shí)
    WaitTime:AMS啟動(dòng)Activity的總耗時(shí)
    (此方式線下使用方便澄者,不能帶到線上。非嚴(yán)謹(jǐn)、精確時(shí)間)

  2. 手動(dòng)打點(diǎn):
    啟動(dòng)時(shí)埋點(diǎn)粱挡,啟動(dòng)結(jié)束時(shí)埋點(diǎn)赠幕,兩者差值。
    寫個(gè)工具類询筏,讀取SystemCurrentTimeMillis

結(jié)束時(shí)間的記錄位置榕堰?真實(shí)數(shù)據(jù)展示出來,F(xiàn)eed第一條展示嫌套。
onWindowFocusChanged不夠準(zhǔn)確逆屡。
getViewTreeObserver 的 addOnPreDrawListener

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

主要兩個(gè)工具:TraceView、Systrace

1. TraceView

圖形的形式展現(xiàn)執(zhí)行時(shí)間踱讨、調(diào)用等魏蔗。信息全面,包含所有線程

使用方式:Debug.startMethodTracing("");
Debug.stopMethodTracing("");

生成文件在sd卡:Android/data/packagename/files
最大能有 8MB的信息痹筛。

圖像分析:
Top Down:Self Time莺治、Total Time (Wall Clock Time、Thread Time)是call Chart 的詳細(xì)文字版本
Call Chart:a調(diào)用b帚稠,那么a 就在 b 的上面谣旁。系統(tǒng)API 橙色、應(yīng)用自己的綠色翁锡,第三放的就是藍(lán)色
Flame Chart:相同調(diào)用順序的過程會(huì)合并在一起蔓挖。
BottomUp:和Top Down相反。
TraceView 運(yùn)行時(shí)開銷嚴(yán)重馆衔,整體都會(huì)變慢。

與CpuProfiler相比怨绣,此工具Android Studio中直接使用角溃。可能需要手速很快才能獲取到篮撑。

2.Systrace

結(jié)合Android 內(nèi)核的數(shù)據(jù)减细,生成一個(gè)Html報(bào)告

API 18 以上使用,推薦TraceCompact

使用方式:
python systrace.py -t 10 [other-options] [categories]

https://developer.android.com/studio/command-line/systrace#command_options

Systrace指令

查看CPU 核心運(yùn)行狀況

UIThread 和 Other Threads的對(duì)比

通過Slice 查看 start 赢笨、wall Duration(代碼執(zhí)行時(shí)間)未蝌、CPU Duration (代碼消耗cpu的時(shí)間)

舉例:鎖沖突

四. 優(yōu)雅獲取方法耗時(shí)講解

常規(guī)方法的侵入性太強(qiáng)。重復(fù)編輯茧妒。

所以萧吠,采用AOP方法(Aspect Oriented Programming 面向切面編程)

  • 針對(duì)同一類問題的統(tǒng)一處理
  • 無侵入添加代碼

AspectJ使用:

classPath ‘com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.0’

implementation 'org.aspectj:aspectjrt:1.8.+'

apply plugin: 'android-aspectjx'

Join Points:程序運(yùn)行時(shí)的執(zhí)行點(diǎn),可以作為切面的地方桐筏。

  • 函數(shù)調(diào)用纸型、執(zhí)行
  • 獲取、設(shè)置變量
  • 類初始化

PointCut:帶條件的JoinPoints (篩選一下某些點(diǎn))
一種Hook,要插入代碼的位置

Before:PointCut之前執(zhí)行狰腌。Advice除破,具體插入位置。

After:PointCut之后執(zhí)行

Around:PointCut之前和之后分別執(zhí)行

execution:處理Join Point 的類型琼腔,call瑰枫、execution
(* android.app.Activity.on**(..)):匹配規(guī)則

onActivityCalled:要插入的代碼

4.1優(yōu)雅獲取方法耗時(shí)實(shí)操

4.2 異步優(yōu)化詳解
優(yōu)化技巧:
Theme切換:感覺上的快。

異步優(yōu)化:
子線程分擔(dān)住線程任務(wù)丹莲,并行減少時(shí)間光坝。

ExecutorService service = Executors.newFixedThreadPool(CORE_POOL_SIZE);

service.submit(new Runnable(){
      public void run(){
          方法分別放入;
      }
});

不符合異步要求的圾笨。部分代碼必須運(yùn)行在主線程當(dāng)中教馆,那么放棄這種異步優(yōu)化的方案。

需要在某階段完成擂达。由于異步執(zhí)行不知道 子任務(wù)何時(shí)結(jié)束钻趋,跳轉(zhuǎn)新界面時(shí) 該方法是否完成弯蚜,

添加

private CountDownLatch mCountDownLatch = new CountDownLatch(1); // 一個(gè)簡(jiǎn)單的開/關(guān)鎖存器

在條件被滿足后

mCountDownLatch.countDown();
try {
          mCountDownLatch.await();
} catch(InterruptedException e){
          e.printStackTrace;
}

4.3 異步初始化最優(yōu)解-啟動(dòng)器-1
充分利用CPU多核,自動(dòng)梳理執(zhí)行順序

  • 代碼Task化,啟動(dòng)邏輯抽象為Task溜哮。
  • 根據(jù)所有任務(wù)以來關(guān)系排序生成一個(gè)有向無環(huán)圖
  • 多線程按照排序后的優(yōu)先級(jí)依次執(zhí)行

4.4 異步初始化最優(yōu)解-啟動(dòng)器-2
TaskDispatcher。并向當(dāng)中要執(zhí)行的Task 分別繼承漆魔,在run方法中進(jìn)行執(zhí)行硝全。

4.5 更優(yōu)秀的延遲初始化方案
常規(guī)方式,回調(diào)方法中執(zhí)行耗時(shí)抄腔。很有可能導(dǎo)致feed 卡頓瓢湃。
對(duì)延遲任務(wù)進(jìn)行分批初始化。

  • 利用IdleHandler特性赫蛇,空閑時(shí)執(zhí)行

4.6 啟動(dòng)優(yōu)化其它方案
異步绵患、延遲、懶加載悟耘。
技術(shù)落蝙、業(yè)務(wù)相結(jié)合。
cpu time才是優(yōu)化方向
按照systrace 及 cpu time 跑滿cpu

IO密集型 和 CPU密集型 操作暂幼。
收斂啟動(dòng)代碼修改權(quán)限筏勒。

結(jié)合Ci修改啟動(dòng)代碼需要Review通知

其他方案:

  • 提前加載SharedPreferences。getSharedPreference load到內(nèi)存中旺嬉。如果沒有完成一直阻塞進(jìn)行等待管行。
  • Multidex之前加載,利用此階段CPU覆寫 getApplicationContext() 返回 this鹰服。 attachBaseContext中
    啟動(dòng)階段不啟動(dòng)子進(jìn)程病瞳,子進(jìn)程會(huì)共享CPU資源揽咕,導(dǎo)致主進(jìn)程CPU緊張。注意啟動(dòng)順序:App onCreate 之前是ContentProvider

類加載優(yōu)化:提前異步加載(可以替換掉系統(tǒng)的ClassLoader套菜,每個(gè)類加載的時(shí)候都打印一個(gè)Log)Class.forName() 只加載類本身及其靜態(tài)變量的引用類亲善。
new 類實(shí)例 可以額外加載類成員變量的引用類
啟動(dòng)階段抑制GC

  • CPU鎖頻

啟動(dòng)速度模擬面試
1)你做啟動(dòng)優(yōu)化是怎么做的?

  • 分析現(xiàn)狀逗柴、確認(rèn)問題蛹头。(目前啟動(dòng)流程復(fù)雜,主線程執(zhí)行了太多的代碼)
  • 針對(duì)性優(yōu)化(實(shí)現(xiàn)異步初始化)簡(jiǎn)單異步 指向了啟動(dòng)器戏溺。
  • 長(zhǎng)期保持優(yōu)化效果渣蜗。

2)是怎么異步的,異步遇到問題沒有旷祸?

  • 異步演進(jìn)過程
  • 詳細(xì)介紹啟動(dòng)器

3)有哪些容易忽略的點(diǎn)耕拷?

  • cpu time 和 wall time。
  • 注意延遲初始化的優(yōu)化
  • 介紹黑科技托享,類加載骚烧。Systrace 可能沒有給滿的CPU,拉高CPU闰围。

4)版本迭代導(dǎo)致的啟動(dòng)變慢有好的解決方式嗎赃绊?

  • 啟動(dòng)器
  • 結(jié)合CI
  • 監(jiān)控完善
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市羡榴,隨后出現(xiàn)的幾起案子碧查,更是在濱河造成了極大的恐慌,老刑警劉巖校仑,帶你破解...
    沈念sama閱讀 222,729評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件忠售,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡迄沫,警方通過查閱死者的電腦和手機(jī)档痪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來邢滑,“玉大人,你說我怎么就攤上這事愿汰±Ш螅” “怎么了?”我有些...
    開封第一講書人閱讀 169,461評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵衬廷,是天一觀的道長(zhǎng)摇予。 經(jīng)常有香客問我,道長(zhǎng)吗跋,這世上最難降的妖魔是什么侧戴? 我笑而不...
    開封第一講書人閱讀 60,135評(píng)論 1 300
  • 正文 為了忘掉前任宁昭,我火速辦了婚禮,結(jié)果婚禮上酗宋,老公的妹妹穿的比我還像新娘积仗。我一直安慰自己,他們只是感情好蜕猫,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,130評(píng)論 6 398
  • 文/花漫 我一把揭開白布寂曹。 她就那樣靜靜地躺著,像睡著了一般回右。 火紅的嫁衣襯著肌膚如雪隆圆。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,736評(píng)論 1 312
  • 那天翔烁,我揣著相機(jī)與錄音渺氧,去河邊找鬼。 笑死蹬屹,一個(gè)胖子當(dāng)著我的面吹牛侣背,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播哩治,決...
    沈念sama閱讀 41,179評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼秃踩,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了业筏?” 一聲冷哼從身側(cè)響起憔杨,我...
    開封第一講書人閱讀 40,124評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蒜胖,沒想到半個(gè)月后消别,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,657評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡台谢,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,723評(píng)論 3 342
  • 正文 我和宋清朗相戀三年寻狂,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片朋沮。...
    茶點(diǎn)故事閱讀 40,872評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蛇券,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出樊拓,到底是詐尸還是另有隱情纠亚,我是刑警寧澤,帶...
    沈念sama閱讀 36,533評(píng)論 5 351
  • 正文 年R本政府宣布筋夏,位于F島的核電站蒂胞,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏条篷。R本人自食惡果不足惜骗随,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,213評(píng)論 3 336
  • 文/蒙蒙 一蛤织、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧鸿染,春花似錦指蚜、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,700評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至丢烘,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間播瞳,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,819評(píng)論 1 274
  • 我被黑心中介騙來泰國打工忧侧, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人牌芋。 一個(gè)月前我還...
    沈念sama閱讀 49,304評(píng)論 3 379
  • 正文 我出身青樓蚓炬,卻偏偏與公主長(zhǎng)得像躺屁,于是被迫代替她去往敵國和親肯夏。 傳聞我的和親對(duì)象是個(gè)殘疾皇子犀暑,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,876評(píng)論 2 361

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