Android 啟動(dòng)卡頓原因查詢

啟動(dòng)是一個(gè)什么樣的過程雪标?首先要對(duì)這個(gè)過程進(jìn)行一個(gè)定義∫楹觯考慮到進(jìn)程是否存在懒闷,對(duì)啟動(dòng)時(shí)間有著明確的影響,將啟動(dòng)分為兩種情況栈幸。

冷啟動(dòng) :在進(jìn)程不存在的情況下愤估,從點(diǎn)擊應(yīng)用 Icon 到用戶能看到界面所占用的時(shí)間。
熱啟動(dòng) :在進(jìn)程依然存在的情況下速址,點(diǎn)擊應(yīng)用 Icon 到用戶能看到對(duì)應(yīng)的界面所用的時(shí)間玩焰。

知道這兩個(gè)啟動(dòng)時(shí)間怎么定義后,需要將這個(gè)進(jìn)行實(shí)際的測(cè)量芍锚。通過這個(gè)測(cè)量時(shí)間的獲得昔园,就能定性地去衡量啟動(dòng)過程的性能問題。性能越好闹炉,所有時(shí)間就會(huì)更少蒿赢,反之就更多。


宏觀測(cè)量 — Adb 命令的使用

那么接下來看看渣触,具體怎么將這個(gè)測(cè)量過程落地羡棵。

Android adb 提供了很簡(jiǎn)單的測(cè)量方式,預(yù)先通過在 FrameWork 層中的 ActivityManagerService 等等中進(jìn)行埋點(diǎn)的方式嗅钻,這樣可以獲得對(duì)應(yīng)的時(shí)間點(diǎn)皂冰。

adb shell am start -W [packageName]/[activityName]

這樣執(zhí)行后,可以得到如下圖所示的樣子养篓。

am_start

這里面涉及到三個(gè)時(shí)間秃流,ThisTime、TotalTime 和 WaitTime柳弄。WaitTime 是 startActivityAndWait 這個(gè)方法的調(diào)用耗時(shí)舶胀,ThisTime 是指調(diào)用過程中最后一個(gè) Activity 啟動(dòng)時(shí)間到這個(gè) Activity 的 startActivityAndWait 調(diào)用結(jié)束。TotalTime 是指調(diào)用過程中第一個(gè) Activity 的啟動(dòng)時(shí)間到最后一個(gè) Activity 的 startActivityAndWait 結(jié)束碧注。如果過程中只有一個(gè) Activity 嚣伐,則 TotalTime 等于 ThisTime。

final long startTime = SystemClock.uptimeMillis();
if (mWaitOption) {
    result = mAm.startActivityAndWait(null, null, intent, mimeType,
                null, null, 0, mStartFlags, profilerInfo, null, mUserId);
    res = result.result;
} else {
    res = mAm.startActivityAsUser(null, null, intent, mimeType,
            null, null, 0, mStartFlags, profilerInfo, null, mUserId);
}
final long endTime = SystemClock.uptimeMillis();

上面是 WaitTime 的計(jì)算方式萍丐,其他時(shí)間的計(jì)算方式也請(qǐng)參考源碼轩端。不過就實(shí)際的使用而言,這種方式得出的時(shí)間逝变,不夠準(zhǔn)確基茵,誤差較大奋构。

在 API 19 后,ActivityManagerService 也通過日志的方式告訴我們 Activity 啟動(dòng)花了多少時(shí)間拱层。

ActivityManager: Displayed com.android.myexample/.StartupTiming: +3s534ms

這個(gè)時(shí)間也可以作為高版本系統(tǒng)中的另一個(gè)宏觀參考指標(biāo)弥臼。

使用這種方式的話,不如在關(guān)鍵時(shí)間點(diǎn)記錄相關(guān)的時(shí)間舱呻,這種方式會(huì)更加直觀一點(diǎn)醋火,粒度也會(huì)更加精細(xì)一些。


精確測(cè)量 — TraceView 的應(yīng)用

大部分人都知道利用 TraceView 進(jìn)行分析箱吕,通過 TraceView 提供的數(shù)據(jù)分析出對(duì)于哪些方法是造成耗時(shí)的緣故芥驳。這里還是要簡(jiǎn)單地介紹一下 TraceView,方便不了解的同學(xué)茬高。

TraceView 位于 Android Devices Monitor 里面兆旬。可以在 Android Studio -》Tools -》Android 中找到 Devices Monitor怎栽。在 Monitor 中就可以打開對(duì)應(yīng)的 Trace 文件丽猬,或者在這里進(jìn)行 Trace 操作。下圖展示的是一個(gè) Trace 界面熏瞄。

TraceView
TraceView 關(guān)鍵指標(biāo)的講解

在上圖中的下部分脚祟,是每個(gè)函數(shù)相關(guān)的調(diào)用信息。左邊是函數(shù)的名稱强饮,右邊是其調(diào)用的各種統(tǒng)計(jì)信息由桌。
Incl Cpu Time: 這個(gè)方法調(diào)用所占據(jù)的時(shí)間。
Excl Cpu Time: 這個(gè)方法本身執(zhí)行的時(shí)間邮丰,例如這個(gè)方法里面調(diào)用了 a, b 兩個(gè)方法行您,Excl 就是排除 a,b 兩者占用的時(shí)間之后的時(shí)間剪廉。
Incl Real Time 等等與前者類似娃循,一個(gè)是 Real time,一個(gè)是 CPU 時(shí)間斗蒋,兩個(gè)區(qū)別不大捌斧。
Calls + Recur Calls / Total: 函數(shù)的調(diào)用次數(shù)(包含了遞歸調(diào)用) / 總次數(shù)。通常用于判斷一些方法是否出現(xiàn)這個(gè)異常泉沾。
Cpu Time / Call: 每個(gè)函數(shù)的平均調(diào)用時(shí)間捞蚂,這個(gè)對(duì)一些常用方法的判斷尤為重要。例如一個(gè) RecyclerView 經(jīng)常調(diào)用 getview 方法爆哑,那么我對(duì)這個(gè)方法里面的優(yōu)化是否生效呢?顯然不能看單個(gè) getview 的耗時(shí)舆吮,而是平均每個(gè) getview 方法的耗時(shí)揭朝。

TraceView 的粗略使用指南

在 Android Devices Monitor 中左側(cè)選中對(duì)應(yīng)的進(jìn)程名队贱,然后點(diǎn)擊如箭頭所指的按鈕,按鈕中紅點(diǎn)將會(huì)變成黑點(diǎn)潭袱,在界面上進(jìn)行相應(yīng)的操作柱嫌,然后再次點(diǎn)擊該按鈕。等待片刻后屯换,界面上就會(huì)出現(xiàn)相應(yīng)的 TraceView 界面编丘,根據(jù)上文所述的指標(biāo)意義,找出問題的癥結(jié)彤悔。

Start Trace

如果是針對(duì)啟動(dòng)問題的話嘉抓,使用這種方式就不太合理了,還沒等你點(diǎn)擊按鈕晕窑,就已經(jīng)執(zhí)行過了抑片。給大家一種技巧,

// 在 /sdcard 目錄下記錄 trace_file.trace 的文件, 開始 trace
Debug.startMethodTracing("trace_file");
// 結(jié)束 trace杨赤,并輸出文件
Debug.stopMethodTracing();

在這種情況下敞斋,只要在啟動(dòng)的前后分別調(diào)用兩個(gè)方法,就能在 sdcard 中找到對(duì)應(yīng)的 trace 文件疾牲。后續(xù)再使用 adb pull 導(dǎo)出植捎,并使用 Android Studio ,或者 Devices Monitor 打開文件阳柔,就能進(jìn)行分析了焰枢。


官方的偷天換日

對(duì)于大型 APK 而言,優(yōu)化并非那么簡(jiǎn)單盔沫,牽涉到很多模塊医咨,某些模塊的初始化必須在此啟動(dòng),在這種情況下架诞,Google 官方教程推出了 Launch-Time Performance | Android Developers 這篇文章拟淮。這里簡(jiǎn)單地介紹下這種偷天換日的方案,讓用戶在體驗(yàn)上感覺應(yīng)用快了那么一點(diǎn)點(diǎn)谴忧。

在啟動(dòng) Activity 之間很泊,系統(tǒng)會(huì)先生成一個(gè)空白的 Window,等到 Activity 的各類資源準(zhǔn)備完畢后沾谓,將其放置到 Window 上去委造。偷天換日的方案就是在這個(gè) window 上做手腳,先將 window 的背景替換成類似于主界面的背景均驶,這樣用戶會(huì)以為此時(shí)界面已經(jīng)在加載中了昏兆。等一段時(shí)間后,再將這個(gè) Window 替換為實(shí)際的 Activity 界面妇穴。

首先指定一個(gè)背景圖爬虱,就像下面的代碼一樣隶债。

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" android:opacity="opaque">
  <!-- The background color, preferably the same as your normal theme -->
  <item android:drawable="@android:color/white"/>
  <!-- Your product logo - 144dp color version of your app icon -->
  <item>
    <bitmap
      android:src="@drawable/product_logo_144dp"
      android:gravity="center"/>
  </item>
</layer-list>

再指定 Activity 的主題到這個(gè) style 文件中。

<activity ...
  android:theme="@style/AppTheme.Launcher" />

最后跑筝,一定要記得在 Activity 的 onCreate 方法里進(jìn)行 Style 替換死讹。

public class MyMainActivity extends AppCompatActivity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
     Make sure this is before calling super.onCreate
    setTheme(R.style.Theme_MyApp);
    super.onCreate(savedInstanceState);
     ...
  }
}

最好的方式還是優(yōu)化代碼結(jié)構(gòu),一勞永逸地解決問題曲梗,這樣才能自豪地說赞警,我就是快!


文檔信息


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末虏两,一起剝皮案震驚了整個(gè)濱河市愧旦,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌碘举,老刑警劉巖忘瓦,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異引颈,居然都是意外死亡耕皮,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門蝙场,熙熙樓的掌柜王于貴愁眉苦臉地迎上來凌停,“玉大人,你說我怎么就攤上這事售滤》D猓” “怎么了?”我有些...
    開封第一講書人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵完箩,是天一觀的道長(zhǎng)赐俗。 經(jīng)常有香客問我,道長(zhǎng)弊知,這世上最難降的妖魔是什么阻逮? 我笑而不...
    開封第一講書人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮秩彤,結(jié)果婚禮上叔扼,老公的妹妹穿的比我還像新娘。我一直安慰自己漫雷,他們只是感情好瓜富,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著降盹,像睡著了一般与柑。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,741評(píng)論 1 289
  • 那天价捧,我揣著相機(jī)與錄音每辟,去河邊找鬼。 笑死干旧,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的妹蔽。 我是一名探鬼主播椎眯,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼胳岂!你這毒婦竟也來了编整?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤乳丰,失蹤者是張志新(化名)和其女友劉穎掌测,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體产园,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡汞斧,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了什燕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片粘勒。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖屎即,靈堂內(nèi)的尸體忽然破棺而出庙睡,到底是詐尸還是另有隱情,我是刑警寧澤技俐,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布乘陪,位于F島的核電站,受9級(jí)特大地震影響雕擂,放射性物質(zhì)發(fā)生泄漏啡邑。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一捂刺、第九天 我趴在偏房一處隱蔽的房頂上張望谣拣。 院中可真熱鬧,春花似錦族展、人聲如沸森缠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽贵涵。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間宾茂,已是汗流浹背瓷马。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留跨晴,地道東北人欧聘。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像端盆,于是被迫代替她去往敵國(guó)和親怀骤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348

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

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,732評(píng)論 25 707
  • 請(qǐng)保持淡定焕妙,分析代碼蒋伦,記住:性能很重要焚鹊。 啟動(dòng)時(shí)間優(yōu)化 毫無疑問痕届,應(yīng)用的啟動(dòng)速度越快越好。 本文可以幫助你優(yōu)化應(yīng)用...
    Mupceet閱讀 11,380評(píng)論 5 19
  • A同學(xué)的救世主(文/小弋婦人) A同學(xué)在異性中的知名度就像今年的高溫一樣持續(xù)上升末患,遍及各地研叫。這不是誰都有的,有的...
    異地狗肉鋪閱讀 293評(píng)論 0 1
  • 窗外的鐵皮雨棚如邊角破損的銅鑼被急驟的敲了幾響璧针,聲音有些渾濁蓝撇,還未聽得仔細(xì),一道驚艷的白從天邊閃過陈莽,不由分說的闖進(jìn)...
    古卯閱讀 370評(píng)論 0 1
  • 唐舒閱讀 314評(píng)論 0 0