Android應(yīng)用快速啟動(dòng)--谷歌官方指南<1>

官方鏈接

一個(gè)留得住用戶的APP體驗(yàn)感一定要好惊畏,應(yīng)用的啟動(dòng)越快恶耽,用戶體驗(yàn)自然就好,用戶體驗(yàn)差颜启,等了半天都沒(méi)出來(lái)偷俭,第一影響就不好,所以我們需要對(duì)應(yīng)用啟動(dòng)以及黑白屏進(jìn)行處理缰盏,快速啟動(dòng)涌萤,給用戶一個(gè)好的體驗(yàn)。最近因?yàn)轫?xiàng)目需要開(kāi)始看這個(gè)問(wèn)題乳规,學(xué)習(xí)一下如何能盡快的啟動(dòng)應(yīng)用形葬。所以就找來(lái)了官方的文檔看看合呐,自己翻譯和選擇性總結(jié)了一下暮的。所以本篇文章和官網(wǎng)不是完全相同。如果有哪里不對(duì)的淌实,歡迎留言改正冻辩。雖然我很多次都希望自己是一個(gè)可以把英文一眼就看穿的人,但是能力還有限拆祈,所以可能哪里不對(duì)恨闪。大家多提出來(lái)。謝謝7呕怠咙咽!好吧廢話這么多了。開(kāi)始吧淤年!

首先钧敞,應(yīng)用啟動(dòng)分為三個(gè)狀態(tài):1.冷啟動(dòng) 2.熱啟動(dòng) 3.溫啟動(dòng)蜡豹。其中冷啟動(dòng)是包括了啟動(dòng)APP,創(chuàng)建APP進(jìn)程,顯示startWindow界面的溉苛。而熱啟動(dòng)和溫啟動(dòng)是界面從不可見(jiàn)到可見(jiàn)的過(guò)程镜廉。我們著重于優(yōu)化冷啟動(dòng),當(dāng)然熱啟動(dòng)和溫啟動(dòng)也可以優(yōu)化愚战。

對(duì)了娇唯,本片文章是Android應(yīng)用快速啟動(dòng)的系列文章的第一篇,也是基礎(chǔ)知識(shí)寂玲。接下來(lái)我會(huì)對(duì)本文中提到的一些知識(shí)塔插,以及工具的使用總結(jié)跟大家分享。敬請(qǐng)期待吧. 寫(xiě)系列文章有利于對(duì)一個(gè)知識(shí)點(diǎn)的持續(xù)跟蹤拓哟,對(duì)我是一種自律和督促佑淀。你也可以試試!看看我能不能堅(jiān)持下去彰檬,如果我可以你也可以伸刃!雞湯一波,加油逢倍!

冷啟動(dòng)

只有應(yīng)用啟動(dòng)了捧颅,系統(tǒng)才會(huì)創(chuàng)建應(yīng)用進(jìn)程。冷啟動(dòng)發(fā)生在應(yīng)用第一次啟動(dòng)或者被系統(tǒng)殺死之后啟動(dòng)的時(shí)候较雕。

冷啟動(dòng)的過(guò)程:

  • 系統(tǒng)層面
  1. 加載app
  2. app加載成功之后碉哑,顯示一個(gè)空白的啟動(dòng)窗口(就是我們平時(shí)啟動(dòng)應(yīng)用看到的黑白屏)。
  3. 創(chuàng)建應(yīng)用進(jìn)程

系統(tǒng)加載完之后就輪到應(yīng)用了亮蒋。

  • 應(yīng)用層面
  1. 創(chuàng)建APP對(duì)象
  2. 加載主線程
  3. 創(chuàng)建主Activity
  4. 加載View
  5. 布局
  6. 繪制視圖

一旦App線程完成了繪制扣典,系統(tǒng)就會(huì)用主Activity替換到空白的啟動(dòng)窗口。至此慎玖,用戶可以開(kāi)始交互了贮尖。

從官網(wǎng)上搞了一張圖來(lái)說(shuō)明一下啟動(dòng)過(guò)程。look

cold-launch.png

在創(chuàng)建APP和創(chuàng)建Activity時(shí)容易引發(fā)性能問(wèn)題趁怔。

APP Creation

主要工作是創(chuàng)建APP對(duì)象湿硝,主線程以及主Activity

Activity Creation

1.初始化數(shù)據(jù)

  1. 調(diào)用構(gòu)造函數(shù)
  2. 調(diào)用oncreate
    onCreate函數(shù)的工作多少和啟動(dòng)時(shí)間息息相關(guān)。 因?yàn)樗虞d布局润努,初始化activity運(yùn)行的對(duì)象关斜。

啟動(dòng)性能分析

  • 初始顯示的時(shí)間

    logcat獲取時(shí)間

    從Android4.4(API 19)開(kāi)始,logcat會(huì)打印一條關(guān)于acitivty顯示時(shí)間的信息--Displayed.這個(gè)時(shí)間包括了啟動(dòng)Activity到Layout顯示的過(guò)程铺浇。包含了一下事件:

    1. 啟動(dòng)APP進(jìn)程
    2. 初始化APP對(duì)象
    3. 創(chuàng)建初始化activity
    4. 加載view
    5. 首次繪制應(yīng)用

打印的樣子呢就長(zhǎng)的跟這個(gè)差不多啦痢畜!

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

注意這個(gè)是系統(tǒng)打印的哦,所以不要再logcat里面通過(guò)應(yīng)用包名來(lái)過(guò)濾,否則你看不到的呢丁稀。
** PS:
Logcat輸出中的“顯示”度量不一定會(huì)捕獲所有資源加載和顯示之前的時(shí)間量:它會(huì)遺漏布局文件中未引用的資源或應(yīng)用程序作為對(duì)象初始化的一部分創(chuàng)建的資源繁涂。 它排除了這些資源,因?yàn)榧虞d它們是一個(gè)內(nèi)嵌的過(guò)程二驰,并且不會(huì)阻止應(yīng)用程序的初始顯示扔罪。所以懶加載數(shù)據(jù)的時(shí)間是不會(huì)計(jì)算到這里面的。切記M叭浮?蠼汀!矗积!**

ADB 命令獲取時(shí)間

adb [-d|-e|-s <serialNumber>] shell am start -S -W
com.example.app/.MainActivity
-c android.intent.category.LAUNCHER
-a android.intent.action.MAIN

abd管理界面或者串口輸入如上命令全肮,就可以獲取到啟動(dòng)某個(gè)Activity花費(fèi)的時(shí)間。
最簡(jiǎn)單的語(yǔ)句就是:

adb shell am start -S -W xxxActivity的完整路徑 

-c棘捣,-a使用來(lái)指定category和action的可選項(xiàng)辜腺。

結(jié)果類(lèi)似:

Starting: Intent
Activity: com.example.app/.MainActivity
ThisTime: 2044
TotalTime: 2044
WaitTime: 2054
Complete

ThisTime:最后一個(gè)啟動(dòng)的Activity的啟動(dòng)耗時(shí)
TotalTime:自己的所有Activity的啟動(dòng)耗時(shí)
WaitTime: ActivityManagerService啟動(dòng)App的Activity時(shí)的總時(shí)間(包括當(dāng)前Activity的onPause()和自己Activity的啟動(dòng))

  • 總的顯示時(shí)間 (Fulltime)
    通過(guò)調(diào)用reportFullyDrawn()方法可以獲取到從應(yīng)用啟動(dòng)到資源加載完成的全部時(shí)間。即包括了懶加載的時(shí)間乍恐,不過(guò)依然記住懶加載是不會(huì)影響應(yīng)用啟動(dòng)的评疗。

log如下:

system_process I/ActivityManager: Fully drawn {package}/.MainActivity: +1s54ms  

上面介紹了應(yīng)用啟動(dòng)的基本知識(shí),下面我們倆看看如何定位應(yīng)用啟動(dòng)的元兇茵烈。

利用AndroidStudio的"Method Tracer tool" 和"Tracer結(jié)合Systracer Tool".關(guān)于Method Tracer tool的使用可以查看官方的文檔MethodTracer.

一般用的比較多的是 Trace和Systrace百匆,因?yàn)椴灰欢梢哉J褂?Method Tracer TOOL".

常見(jiàn)的問(wèn)題

谷歌官方列舉了經(jīng)常會(huì)影響APP啟動(dòng)性能的常見(jiàn)問(wèn)題。

Application初始化負(fù)載

Applcation oncreate 有很多耗時(shí)的操作呜投。比如數(shù)據(jù)庫(kù)訪問(wèn)加匈,IO操作之類(lèi)的。

所以不要在這些方法里面做耗時(shí)的操作仑荐,解決方案下面將講解雕拼。

  • 問(wèn)題解決

    對(duì)于數(shù)據(jù)的加載,如果不是里面需要的數(shù)據(jù)粘招,可以改成懶加載方式啥寇。對(duì)于靜態(tài)的對(duì)象,可以轉(zhuǎn)換成單例對(duì)象男图,這樣只會(huì)在第一次初始化該對(duì)象示姿。官方建議可以使用Dagger來(lái)實(shí)現(xiàn)依賴注入甜橱。這樣只會(huì)在第一次的時(shí)候注入.

Activity初始化負(fù)載

Activity創(chuàng)建的時(shí)候常常做了很多開(kāi)銷(xiāo)很大的工作逊笆。對(duì)于這種情況,有很多可以優(yōu)化的地方岂傲。

  1. 加載大而復(fù)雜的布局
  2. 網(wǎng)絡(luò)操作和磁盤(pán)操作堵塞布局繪制
  3. 解碼加載bitmap
  4. 柵格化VectorDrawable對(duì)象
  5. 初始化activity的其他一些子對(duì)象
  • 問(wèn)題解決

    通過(guò)tracer定位問(wèn)題难裆,然后解決。

    1. 如果你的布局過(guò)于復(fù)雜就會(huì)加大啟動(dòng)activity的時(shí)間,所以盡量?jī)?yōu)化你的布局
    • 除掉冗余和嵌套的布局乃戈,可以通過(guò)lint來(lái)檢測(cè)代碼褂痰,lint會(huì)對(duì)布局進(jìn)行檢測(cè)。
    • 不要加載在啟動(dòng)Activity時(shí)症虑,不需要可見(jiàn)的布局缩歪,利用ViewStub,通過(guò)這個(gè)可以在適當(dāng)?shù)臅r(shí)間加載布局。
    1. 在主線程加載所有的資源也會(huì)拖慢加載的速度谍憔。
    • 在非主線程加載數(shù)據(jù)匪蝙,懶加載。當(dāng)然在不影響你的需求的情況下习贫,把能異步加載的異步加載逛球。
    • 先顯示布局,對(duì)于圖片等的加載可以延遲加載
    1. Activity oncreate苫昌,onResume颤绕,onstart耗時(shí)過(guò)多,如果還有上一個(gè)Activity祟身,上一個(gè)Activity的onPaues也能有太多耗時(shí)因?yàn)檫@也會(huì)影響APP啟動(dòng)的性能奥务。所以呢不要在這里沒(méi)進(jìn)行不必要的耗時(shí)操作。

不根治但是實(shí)用的解決辦法

通過(guò)設(shè)置theme來(lái)避免黑白屏袜硫,類(lèi)似于展示一個(gè)閃屏汗洒。等Activity加載好之后就會(huì)顯示Activity。
具體做法:

  • 定義一個(gè)Drawable文件父款,然后在AndroidMainfest.xml文件里面將主題設(shè)置給對(duì)應(yīng)的Actvity溢谤,最后在該Activity的oncreate方法的setContentView之前將主題設(shè)置回來(lái)。
    代碼如下:
drawable示例:
<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>  

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

Activity onCreate示例:

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);
    // ...
  }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末憨攒,一起剝皮案震驚了整個(gè)濱河市世杀,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌肝集,老刑警劉巖瞻坝,帶你破解...
    沈念sama閱讀 216,324評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異杏瞻,居然都是意外死亡所刀,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)捞挥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)浮创,“玉大人,你說(shuō)我怎么就攤上這事砌函≌杜” “怎么了溜族?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,328評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)垦沉。 經(jīng)常有香客問(wèn)我煌抒,道長(zhǎng),這世上最難降的妖魔是什么厕倍? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,147評(píng)論 1 292
  • 正文 為了忘掉前任寡壮,我火速辦了婚禮,結(jié)果婚禮上讹弯,老公的妹妹穿的比我還像新娘诬像。我一直安慰自己,他們只是感情好闸婴,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,160評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布坏挠。 她就那樣靜靜地躺著,像睡著了一般邪乍。 火紅的嫁衣襯著肌膚如雪降狠。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,115評(píng)論 1 296
  • 那天庇楞,我揣著相機(jī)與錄音榜配,去河邊找鬼。 笑死吕晌,一個(gè)胖子當(dāng)著我的面吹牛蛋褥,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播睛驳,決...
    沈念sama閱讀 40,025評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼烙心,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了乏沸?” 一聲冷哼從身側(cè)響起淫茵,我...
    開(kāi)封第一講書(shū)人閱讀 38,867評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蹬跃,沒(méi)想到半個(gè)月后匙瘪,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,307評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蝶缀,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,528評(píng)論 2 332
  • 正文 我和宋清朗相戀三年丹喻,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片翁都。...
    茶點(diǎn)故事閱讀 39,688評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡碍论,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出荐吵,到底是詐尸還是另有隱情骑冗,我是刑警寧澤赊瞬,帶...
    沈念sama閱讀 35,409評(píng)論 5 343
  • 正文 年R本政府宣布先煎,位于F島的核電站贼涩,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏薯蝎。R本人自食惡果不足惜遥倦,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,001評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望占锯。 院中可真熱鬧袒哥,春花似錦、人聲如沸消略。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,657評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)艺演。三九已至却紧,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間胎撤,已是汗流浹背晓殊。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,811評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留伤提,地道東北人巫俺。 一個(gè)月前我還...
    沈念sama閱讀 47,685評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像肿男,于是被迫代替她去往敵國(guó)和親介汹。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,573評(píng)論 2 353

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

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,070評(píng)論 25 707
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理舶沛,服務(wù)發(fā)現(xiàn)痴昧,斷路器,智...
    卡卡羅2017閱讀 134,651評(píng)論 18 139
  • 請(qǐng)保持淡定冠王,分析代碼赶撰,記住:性能很重要柱彻。 啟動(dòng)時(shí)間優(yōu)化 毫無(wú)疑問(wèn)豪娜,應(yīng)用的啟動(dòng)速度越快越好。 本文可以幫助你優(yōu)化應(yīng)用...
    Mupceet閱讀 11,393評(píng)論 5 19
  • 小Z朋友在電信行業(yè)上班哟楷,有天給我們講了件奇葩的事瘤载。怎么奇葩呢,用戶朋友通過(guò)第三方平臺(tái)給用戶交了幾十元話費(fèi)卖擅,這用戶的...
    蜜甜水淡閱讀 181評(píng)論 0 0
  • 我不知道那樣瘋狂放手一搏鸣奔,效果到底會(huì)怎樣……但我知道如果不那么做墨技,將來(lái)自己一定會(huì)后悔。成功需要努力挎狸,也需要運(yùn)氣……...
    盆栽多肉Swag閱讀 620評(píng)論 0 0