淺談Android啟動(dòng)時(shí)間

【觸發(fā)背景】面對(duì)海量APP的今天笨鸡,APP用戶量和活躍度成為評(píng)價(jià)一款A(yù)PP是否成功的重要因素狸眼。用戶下載APP后,APP性能體驗(yàn)比如啟動(dòng)時(shí)間谢鹊,直接影響用戶使用頻率算吩,甚至決定是否卸載APP。想和大家分享【APP性能關(guān)于啟動(dòng)時(shí)間】的資料和心得佃扼。

一偎巢、APP啟動(dòng)方式

通常來(lái)說(shuō),APP中啟動(dòng)方式分為兩種:冷啟動(dòng)和熱啟動(dòng)松嘶。
1.冷啟動(dòng):當(dāng)啟動(dòng)應(yīng)用時(shí)艘狭,后臺(tái)沒(méi)有該應(yīng)用的進(jìn)程,這時(shí)系統(tǒng)會(huì)重新創(chuàng)建一個(gè)新的進(jìn)程分配給該應(yīng)用翠订,這個(gè)啟動(dòng)方式就是冷啟動(dòng)巢音。

2.熱啟動(dòng):當(dāng)啟動(dòng)應(yīng)用時(shí),后臺(tái)已有該應(yīng)用的進(jìn)程(例:按back鍵/home鍵尽超,應(yīng)用雖然會(huì)退出官撼,但是該應(yīng)用的進(jìn)程是依然會(huì)保留在后臺(tái),可進(jìn)入任務(wù)列表查看)似谁,所以在已有進(jìn)程的情況下傲绣,這種啟動(dòng)會(huì)從已有的進(jìn)程中來(lái)啟動(dòng)應(yīng)用掠哥,這個(gè)方式叫熱啟動(dòng)。

請(qǐng)注意:上面說(shuō)的啟動(dòng)是點(diǎn)擊app的啟動(dòng)圖標(biāo)來(lái)啟動(dòng)的秃诵,而另外一種方式是進(jìn)入最近使用的列表界面來(lái)啟動(dòng)應(yīng)用续搀,這種不應(yīng)該叫啟動(dòng),應(yīng)該叫恢復(fù)菠净。

以Android系統(tǒng)舉例

冷啟動(dòng):冷啟動(dòng)后系統(tǒng)會(huì)重新創(chuàng)建一個(gè)新的進(jìn)程分配給它禁舷,所以先創(chuàng)建和初始化Application類,再創(chuàng)建和初始化MainActivity類(包括一系列的測(cè)量毅往、布局牵咙、繪制),最后經(jīng)過(guò)渲染顯示在app界面攀唯。
熱啟動(dòng):熱啟動(dòng)因?yàn)闀?huì)從已有的進(jìn)程中來(lái)啟動(dòng)洁桌,所以熱啟動(dòng)就不會(huì)走Application這步了,而是直接走M(jìn)ainActivity(包括一系列的測(cè)量侯嘀、布局另凌、繪制),所以熱啟動(dòng)的過(guò)程只需要?jiǎng)?chuàng)建和初始化一個(gè)MainActivity就行了戒幔,而不必創(chuàng)建和初始化Application途茫,因?yàn)橐粋€(gè)應(yīng)用從新進(jìn)程的創(chuàng)建到進(jìn)程的銷毀,Application只會(huì)初始化一次溪食。

Android系統(tǒng)上,APP無(wú)進(jìn)程狀態(tài)娜扇,啟動(dòng)流程見(jiàn)下:
Application的構(gòu)造器方法 ——>attachBaseContext() ——>onCreate() ——>Activity的構(gòu)造方法 ——>onCreate() ——>配置主題中背景等屬性 ——>onStart() ——>onResume() ——>測(cè)量布局繪制顯示在界面上错沃。

當(dāng)點(diǎn)擊APP的啟動(dòng)圖標(biāo)時(shí),安卓系統(tǒng)會(huì)從Zygote進(jìn)程中fork創(chuàng)建出一個(gè)新的進(jìn)程分配給該應(yīng)用雀瓢,之后會(huì)依次創(chuàng)建和初始化Application類枢析、創(chuàng)建MainActivity類、加載主題樣式Theme中的windowBackground等屬性設(shè)置給MainActivity以及配置Activity層級(jí)上的一些屬性刃麸、再inflate布局醒叁、當(dāng)onCreate/onStart/onResume方法都走完了后最后才進(jìn)行contentView的measure/layout/draw顯示在界面上,所以直到這里泊业,應(yīng)用的第一次啟動(dòng)才算完成把沼,這時(shí)候我們看到的界面也就是所說(shuō)的第一幀。

Android啟動(dòng)流程原理詳情請(qǐng)點(diǎn)擊這里

二吁伺、什么是啟動(dòng)時(shí)間饮睬?
1.冷啟動(dòng)時(shí)間
當(dāng)用戶點(diǎn)擊目標(biāo)app圖標(biāo)的 timepoint到顯示界面第一幀的時(shí)間段(當(dāng)用戶點(diǎn)擊你的app那一刻到系統(tǒng)調(diào)用Activity.onCreate()之間的時(shí)間段)
在這個(gè)時(shí)間段內(nèi),WindowManager會(huì)先加載app主題樣式中的windowBackground做為app的預(yù)覽元素篮奄,然后再真正去加載activity的layout布局捆愁。

2.熱啟動(dòng)時(shí)間
用戶把目標(biāo)app切換至后臺(tái)后割去,點(diǎn)擊app圖標(biāo)的timepoint到顯示界面第一幀的時(shí)間段

3.過(guò)程
首先我們要知道當(dāng)打開(kāi)一個(gè)Activity的時(shí)候發(fā)生了什么,在一個(gè)Activity打開(kāi)時(shí)昼丑,如果該Activity所屬的Application還沒(méi)有啟動(dòng)呻逆,那么系統(tǒng)會(huì)為這個(gè)Activity創(chuàng)建一個(gè)進(jìn)程(每創(chuàng)建一個(gè)進(jìn)程都會(huì)調(diào)用一次Application,所以Application的onCreate()方法可能會(huì)被調(diào)用多次)菩帝,在進(jìn)程的創(chuàng)建和初始化中咖城,勢(shì)必會(huì)消耗一些時(shí)間,在這個(gè)時(shí)間里胁附,WindowManager會(huì)先加載APP里的主題樣式里的窗口背景(windowBackground)作為預(yù)覽元素酒繁,然后才去真正的加載布局。如果加載windowBackground時(shí)間過(guò)長(zhǎng)控妻,而默認(rèn)的背景又是黑色或者白色州袒,這樣會(huì)給用戶造成一種錯(cuò)覺(jué),APP不流暢弓候,影響用戶體驗(yàn)郎哭。

【補(bǔ)充解釋】WindowManager:Windows Manager是一款窗口管理終端,可以遠(yuǎn)程連接到Linux的X桌面進(jìn)行管理菇存,與服務(wù)器端產(chǎn)生一個(gè)session相互通信夸研。詳情請(qǐng)點(diǎn)擊這里

三、使用命令獲得啟動(dòng)時(shí)間

使用命令獲得啟動(dòng)時(shí)間
$adb shell am start -W -n packagename/packageName.MainActivity

1.獲得packagename和入口MainActivity信息
$ aapt dump badging <apk路徑>
搜'package' 'launchable-activity',獲得如下信息

0DB01250-05A2-43FC-BCF8-DDCA09DFA9AA.png
74BA413B-B5B0-4B8B-8FA5-4034050FE793.png

2.獲得packagename依鸥、入口MainActivity亥至,填入命令

B2E37528-4F3A-47ED-937D-29E39A9D162F.png

3.得到結(jié)果
1)冷啟動(dòng)結(jié)果:

629C8139-AEED-4FCD-A0D4-FCCA4C8E7FD6.png

2)熱啟動(dòng)結(jié)果:

E724720F-DA74-4187-B851-5A98C8999445.png

4.啟動(dòng)時(shí)間數(shù)據(jù)分析

執(zhí)行成功后將返回三個(gè)測(cè)量到的時(shí)間:

1)ThisTime:一般和TotalTime時(shí)間一樣,除非在應(yīng)用啟動(dòng)時(shí)開(kāi)了一個(gè)透明的Activity預(yù)先處理一些事再顯示出主Activity贱迟,這樣將比TotalTime小姐扮。
2)TotalTime:應(yīng)用的啟動(dòng)時(shí)間,包括創(chuàng)建進(jìn)程+Application初始化+Activity初始化到界面顯示衣吠。
3)WaitTime:一般比TotalTime大點(diǎn)茶敏,包括系統(tǒng)影響的耗時(shí)。

關(guān)于ThisTime/TotalTime/WaitTime的區(qū)別,下面是其解釋:“adb shell am start -W ”的實(shí)現(xiàn)在『frameworks\base\cmds\am\src\com\android\commands\am\Am.java』文件中缚俏。其實(shí)就是跨Binder調(diào)用ActivityManagerService.startActivityAndWait() 接口(后面將ActivityManagerService簡(jiǎn)稱為AMS)惊搏,這個(gè)接口返回的結(jié)果包含上面打印的ThisTime、TotalTime時(shí)間.

  • startTime記錄的剛準(zhǔn)備調(diào)用startActivityAndWait()的時(shí)間點(diǎn)
  • endTime記錄的是startActivityAndWait()函數(shù)調(diào)用返回的時(shí)間點(diǎn)
  • WaitTime = startActivityAndWait()調(diào)用耗時(shí)忧换。

ThisTime恬惯、TotalTime 的計(jì)算在 frameworks\base\services\core\java\com\android\server\am\ActivityRecord.java 文件的 reportLaunchTimeLocked() 函數(shù)中。

F78E77FE-97FE-4647-94DC-58EA1C4BCFE9.png
  • curTime表示該函數(shù)調(diào)用的時(shí)間點(diǎn).
  • displayStartTime表示一連串啟動(dòng)Activity中的最后一個(gè)Activity的啟動(dòng)時(shí)間點(diǎn).
  • mLaunchStartTime表示一連串啟動(dòng)Activity中第一個(gè)Activity的啟動(dòng)時(shí)間點(diǎn).
51B3F8CB-AE1C-4525-BBE8-227BFF289BD6.png

其余參考資料亚茬,詳情請(qǐng)點(diǎn)擊這里

四宿崭、競(jìng)品結(jié)果分析
判斷是否存在優(yōu)化必要性:對(duì)比競(jìng)品是否存在明顯延時(shí)。

【競(jìng)品產(chǎn)品】A銀行才写、B銀行葡兑,
【背景】為保證數(shù)據(jù)不被其他app影響奖蔓,重啟手機(jī)后,只開(kāi)啟被測(cè)app
【目的】對(duì)比競(jìng)品讹堤,檢查冷啟動(dòng)時(shí)間
【測(cè)試方法】
1重啟手機(jī)后等2min吆鹤,啟動(dòng)app,觀察冷啟動(dòng)時(shí)間
2kill進(jìn)程洲守,啟動(dòng)app疑务,觀察冷啟動(dòng)時(shí)間
ps: 重啟手機(jī)后立即啟動(dòng)你的App的可能會(huì)受到系統(tǒng)自啟動(dòng)app的影響

輸入命令,查詢結(jié)果:
A銀行
1.重啟手機(jī)后等2min梗醇,啟動(dòng)app知允,觀察冷啟動(dòng)時(shí)間

0C864430-E860-4488-802F-C7F5E4C15E24.png

2.kill進(jìn)程,啟動(dòng)app叙谨,觀察冷啟動(dòng)時(shí)間

EFCCEE73-6E77-498E-B3A7-3861CEDEC347.png

B銀行
1.重啟手機(jī)后等2min温鸽,啟動(dòng)APP,觀察冷啟動(dòng)時(shí)間

B73453C2-146E-47F4-ADFB-17EA6A2C204E.png

2.kill進(jìn)程手负,啟動(dòng)APP涤垫,觀察冷啟動(dòng)時(shí)間

EB826749-6114-4D4E-A0A8-EBA16E6C5345.png

提取TotalTime對(duì)比,分析結(jié)果:
1.重啟手機(jī)后等2min竟终,啟動(dòng)app蝠猬,觀察冷啟動(dòng)時(shí)間
A銀行TotalTime:1523ms

B銀行TotalTime:510ms
【結(jié)論】通過(guò)對(duì)比可以看到,重啟手機(jī)后统捶,B銀行冷啟動(dòng)時(shí)間明顯優(yōu)于A銀行冷啟動(dòng)時(shí)間

2.kill進(jìn)程榆芦,啟動(dòng)APP,觀察冷啟動(dòng)時(shí)間
A銀行TotalTime:1319ms
B銀行TotalTime:130ms

【結(jié)論】通過(guò)對(duì)比可以看到喘鸟,kill進(jìn)程歧杏,啟動(dòng)APP,B銀行冷啟動(dòng)時(shí)間明顯優(yōu)于A銀行冷啟動(dòng)時(shí)間

3.重啟手機(jī)和kill進(jìn)程迷守,啟動(dòng)APP
A銀行
重啟手機(jī)TotalTime:1523ms
kill進(jìn)程,啟動(dòng)APPTotalTime:1319ms
B銀行
重啟手機(jī)TotalTime:510ms
kill進(jìn)程旺入,啟動(dòng)APPTotalTime:130ms
【結(jié)論】通過(guò)對(duì)比可以看到兑凿,kill進(jìn)程后啟動(dòng)APP,冷啟動(dòng)時(shí)間更快

五茵瘾、優(yōu)化建議
1.減少應(yīng)用啟動(dòng)時(shí)的耗時(shí)
針對(duì)冷啟動(dòng)時(shí)候的一些耗時(shí)礼华,如上測(cè)得這個(gè)應(yīng)用算是中型的app,在冷啟動(dòng)的時(shí)候耗時(shí)已經(jīng)快xxx ms了拗秘,如果項(xiàng)目再大點(diǎn)在Application中配置了更多的初始化操作圣絮,這樣將可能達(dá)到xx s,這樣每次啟動(dòng)都明顯感覺(jué)延遲雕旨,所以app初始化時(shí)考慮如下操作:消除啟動(dòng)時(shí)的白屏/黑屏

在用戶點(diǎn)擊手機(jī)桌面APP的時(shí)候扮匠,看到的黑屏或者白屏其實(shí)是界面渲染前的第一幀捧请,可將Theme里的windowBackground設(shè)置成希望用戶看到的頁(yè)面:

a 將背景圖設(shè)置成我們APP的Logo圖,作為APP啟動(dòng)的引導(dǎo)棒搜,現(xiàn)在市面上大部分的APP也是這么做的疹蛉。

<style name="AppWelcome" parent="AppTheme">
<item name="android:windowBackground">@mipmap/bg_welcome_start</item>
</style>

b 將背景顏色設(shè)置為透明色,這樣當(dāng)用戶點(diǎn)擊桌面APP圖片的時(shí)候力麸,并不會(huì)"立即"進(jìn)入APP可款,而且在桌面上停留一會(huì),其實(shí)這時(shí)候APP已經(jīng)是啟動(dòng)的了克蚂,只是我們心機(jī)的把Theme里的windowBackground的顏色設(shè)置成透明的闺鲸,用戶體驗(yàn)到延遲也會(huì)覺(jué)得是手機(jī)硬件系統(tǒng)導(dǎo)致的,非APP導(dǎo)致的埃叭,降低用戶對(duì)APP指責(zé)度摸恍。

<style name="Appwelcome" parent="android:Theme.Translucent.NoTitleBar.Fullscreen"/>

ps:透明化這種做法需要注意的一點(diǎn),如果直接把Theme引入Activity游盲,在運(yùn)行的時(shí)候可能會(huì)出現(xiàn)如下異常:

java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.

這個(gè)是因?yàn)槭褂昧瞬患嫒莸腡heme误墓,例如Activity繼承了AppCompatActivity,解決方案很簡(jiǎn)單:

  • 1)讓其Activity集成Activity而不要集成兼容性的AppCompatActivity
  • 2)在onCreate()方法里的super.onCreate(savedInstanceState)之前設(shè)置我們?cè)瓉?lái)APP的Theme

public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(R.style.AppTheme);
super.onCreate(savedInstanceState);
}
}

上面的2種做法益缎,我們都需要將Theme引入對(duì)應(yīng)的Activity

<activity
  android:name=".app.main.MainActivity"
  android:theme="@style/AppWelcome"
  android:screenOrientation="portrait">
  <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
  </intent-filter>
</activity>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末谜慌,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子莺奔,更是在濱河造成了極大的恐慌欣范,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,561評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件令哟,死亡現(xiàn)場(chǎng)離奇詭異恼琼,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)屏富,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門晴竞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人狠半,你說(shuō)我怎么就攤上這事噩死。” “怎么了神年?”我有些...
    開(kāi)封第一講書人閱讀 157,162評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵已维,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我已日,道長(zhǎng)垛耳,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 56,470評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮堂鲜,結(jié)果婚禮上栈雳,老公的妹妹穿的比我還像新娘。我一直安慰自己泡嘴,他們只是感情好甫恩,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,550評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著酌予,像睡著了一般磺箕。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上抛虫,一...
    開(kāi)封第一講書人閱讀 49,806評(píng)論 1 290
  • 那天松靡,我揣著相機(jī)與錄音,去河邊找鬼建椰。 笑死雕欺,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的棉姐。 我是一名探鬼主播屠列,決...
    沈念sama閱讀 38,951評(píng)論 3 407
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼伞矩!你這毒婦竟也來(lái)了笛洛?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 37,712評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤乃坤,失蹤者是張志新(化名)和其女友劉穎苛让,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體湿诊,經(jīng)...
    沈念sama閱讀 44,166評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡狱杰,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,510評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了厅须。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片仿畸。...
    茶點(diǎn)故事閱讀 38,643評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖朗和,靈堂內(nèi)的尸體忽然破棺而出错沽,到底是詐尸還是另有隱情,我是刑警寧澤例隆,帶...
    沈念sama閱讀 34,306評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站抢蚀,受9級(jí)特大地震影響镀层,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,930評(píng)論 3 313
  • 文/蒙蒙 一唱逢、第九天 我趴在偏房一處隱蔽的房頂上張望吴侦。 院中可真熱鬧,春花似錦坞古、人聲如沸备韧。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,745評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)织堂。三九已至,卻和暖如春奶陈,著一層夾襖步出監(jiān)牢的瞬間易阳,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,983評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工吃粒, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留潦俺,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,351評(píng)論 2 360
  • 正文 我出身青樓徐勃,卻偏偏與公主長(zhǎng)得像事示,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子僻肖,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,509評(píng)論 2 348

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

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,769評(píng)論 25 707
  • 轉(zhuǎn)載http://www.cnblogs.com/xunzhi/p/5794793.html 一肖爵、應(yīng)用的啟動(dòng)方式 ...
    聰_0b56閱讀 1,204評(píng)論 0 0
  • 最近一直想整理一個(gè)關(guān)于Android熱啟動(dòng)遏匆,冷啟動(dòng)的文章,于是就有了下文(本文僅僅只是整理總結(jié)前人的知識(shí)點(diǎn))來(lái)源:...
    忘塵And閱讀 2,912評(píng)論 0 7
  • 諸位也許看過(guò)山西小院谁榜,那些癌癥的病患幅聘,醫(yī)生都放棄治療,但是他們一心放下對(duì)于疾病的這個(gè)念頭窃植,不再想這些帝蒿,專心讀經(jīng)念佛...
    白語(yǔ)金言閱讀 1,253評(píng)論 0 1
  • 今夜不能讓它脫離了記憶今晚怎能使其逃避了唏噓一筆一筆,-------都看仔細(xì)記錄在觥籌交錯(cuò)的清單里 你我都有走在黑...
    徐人雙閱讀 174評(píng)論 2 1