Android的冷熱啟動(dòng)

轉(zhuǎn)載http://www.cnblogs.com/xunzhi/p/5794793.html

一罐柳、應(yīng)用的啟動(dòng)方式

通常來(lái)說(shuō),啟動(dòng)方式分為兩種:冷啟動(dòng)和熱啟動(dòng)狰住。

1张吉、冷啟動(dòng):當(dāng)啟動(dòng)應(yīng)用時(shí),后臺(tá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)。

特點(diǎn)

1冬耿、冷啟動(dòng):冷啟動(dòng)因?yàn)橄到y(tǒng)會(huì)重新創(chuàng)建一個(gè)新的進(jìn)程分配給它舌菜,所以會(huì)先創(chuàng)建和初始化Application類萌壳,再創(chuàng)建和初始化MainActivity類(包括一系列的測(cè)量亦镶、布局、繪制)袱瓮,最后顯示在界面上缤骨。

2、熱啟動(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ì)初始化一次。

二怪瓶、應(yīng)用的啟動(dòng)過(guò)程

冷啟動(dòng)啟動(dòng)流程:當(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ō)的第一幀蜜唾。所以帖旨,總結(jié)一下,應(yīng)用的啟動(dòng)流程如下:

Application的構(gòu)造器方法——>attachBaseContext()——>onCreate()——>Activity的構(gòu)造方法——>onCreate()——>配置主題中背景等屬性——>onStart()——>onResume()——>測(cè)量布局繪制顯示在界面上灵妨。

大致流程如下:

1解阅、點(diǎn)擊桌面圖標(biāo),Launcher會(huì)啟動(dòng)程序默認(rèn)的Acticity泌霍,之后再按照程序的邏輯啟動(dòng)各種Activity

2货抄、啟動(dòng)Activity都需要借助應(yīng)用程序框架層的ActivityManagerService服務(wù)進(jìn)程(Service也是由ActivityManagerService進(jìn)程來(lái)啟動(dòng)的);在Android應(yīng)用程序框架層中朱转,ActivityManagerService是一個(gè)非常重要的接口蟹地,

它不但負(fù)責(zé)啟動(dòng)Activity和Service,還負(fù)責(zé)管理Activity和Service藤为。

Step 1. 無(wú)論是通過(guò)Launcher來(lái)啟動(dòng)Activity怪与,還是通過(guò)Activity內(nèi)部調(diào)用startActivity接口來(lái)啟動(dòng)新的Activity,都通過(guò)Binder進(jìn)程間通信進(jìn)入到ActivityManagerService進(jìn)程中缅疟,并且調(diào)用ActivityManagerService.startActivity接口分别;

Step 2. ActivityManagerService調(diào)用ActivityStack.startActivityMayWait來(lái)做準(zhǔn)備要啟動(dòng)的Activity的相關(guān)信息;

Step 3. ActivityStack通知ApplicationThread要進(jìn)行Activity啟動(dòng)調(diào)度了存淫,這里的ApplicationThread代表的是調(diào)用ActivityManagerService.startActivity接口的進(jìn)程耘斩,對(duì)于通過(guò)點(diǎn)擊應(yīng)用程序圖標(biāo)的情景來(lái)說(shuō),這個(gè)進(jìn)程就是Launcher了桅咆,

而對(duì)于通過(guò)在Activity內(nèi)部調(diào)用startActivity的情景來(lái)說(shuō)括授,這個(gè)進(jìn)程就是這個(gè)Activity所在的進(jìn)程了;

Step 4. ApplicationThread不執(zhí)行真正的啟動(dòng)操作岩饼,它通過(guò)調(diào)用ActivityManagerService.activityPaused接口進(jìn)入到ActivityManagerService進(jìn)程中荚虚,看看是否需要?jiǎng)?chuàng)建新的進(jìn)程來(lái)啟動(dòng)Activity;

Step 5. 對(duì)于通過(guò)點(diǎn)擊應(yīng)用程序圖標(biāo)來(lái)啟動(dòng)Activity的情景來(lái)說(shuō)籍茧,ActivityManagerService在這一步中版述,會(huì)調(diào)用startProcessLocked來(lái)創(chuàng)建一個(gè)新的進(jìn)程,而對(duì)于通過(guò)在Activity內(nèi)部調(diào)用startActivity來(lái)啟動(dòng)新的Activity來(lái)說(shuō)硕糊,這一步是不需要執(zhí)行的院水,

因?yàn)樾碌腁ctivity就在原來(lái)的Activity所在的進(jìn)程中進(jìn)行啟動(dòng);

Step 6. ActivityManagerServic調(diào)用ApplicationThread.scheduleLaunchActivity接口简十,通知相應(yīng)的進(jìn)程執(zhí)行啟動(dòng)Activity的操作檬某;

Step 7. ApplicationThread把這個(gè)啟動(dòng)Activity的操作轉(zhuǎn)發(fā)給ActivityThread,ActivityThread通過(guò)ClassLoader導(dǎo)入相應(yīng)的Activity類螟蝙,然后把它啟動(dòng)起來(lái)恢恼。

三、冷啟動(dòng)過(guò)程中碰到的白屏黑屏以及優(yōu)化啟動(dòng)時(shí)間

1胰默、白屏問(wèn)題 :

android studio升級(jí) 2.0之后 加上Instant Run场斑,Instant Run為了能夠讓我們快速部署代碼漓踢,背后其實(shí)是有一套非常復(fù)雜的邏輯的,比如要在APK中建立服務(wù)器與Android Studio進(jìn)行通信漏隐,以及代碼差異比對(duì)和替換等喧半,在研發(fā)過(guò)程中可能出現(xiàn)白屏問(wèn)題,

一般release版的程序是不會(huì)出現(xiàn)這種現(xiàn)象的青责;

如果接下來(lái)還會(huì)出現(xiàn)白屏問(wèn)題挺据,可以查看style文件

1

...... true true

加入了兩個(gè)屬性,windowIsTranslucent和windowNoTitle脖隶,將這兩個(gè)屬性都設(shè)置成true扁耐,就可以讓程序在初始化的時(shí)候窗口是透明的,初始化結(jié)束后程序主界面才會(huì)顯示出來(lái)产阱,從而也就完全看不到白屏界面了

2婉称、啟動(dòng)時(shí)間的優(yōu)化

先測(cè)量activity的啟動(dòng)時(shí)間-------Activity的reportFullyDrawn()方法

你就需要調(diào)用Activity的reportFullyDrawn()。它將在log里報(bào)告從apk初始化(和前面Displayed的時(shí)間是一樣的)到reportFullyDrawn() 方法被調(diào)用用了多長(zhǎng)時(shí)間构蹬。

reportFullyDrawn()方法顯示的log也是類似這樣:

ActivityManager: Displayed com.Android.myexample/.StartupTiming: +768ms

在4.4上調(diào)用reportFullyDrawn()方法會(huì)崩潰(但是log還是能正常打油醢怠),提示需要UPDATE_DEVICE_STATS權(quán)限?怎燥,但是這個(gè)權(quán)限只有系統(tǒng)app才能授權(quán)瘫筐。解決的辦法是這樣調(diào)

try{

reportFullyDrawn();

}catch(SecurityException?e){

}

還有一種測(cè)量啟動(dòng)時(shí)間的方法也值得一提,那就是screenrecord命令

首先啟動(dòng)帶—bugreport選項(xiàng)(它可以在frames 中添加時(shí)間戳-應(yīng)該是L中的特性)的screenrecord 命令:

$?adb?shell?screenrecord?--bugreport?/sdcard/launch.mp4

然后點(diǎn)擊app的圖標(biāo)铐姚,等待app顯示,ctrl-C screenrecord, 使用adb pull命令把文件導(dǎo)出到電腦肛捍。

$?adb?pull?/sdcard/launch.mp4

現(xiàn)在你可以打開錄制視頻看看發(fā)生了什么隐绵。你需要一個(gè)能逐幀查看的視頻播放器(mac上的Quicktime 就可以,不清楚其它os上什么播放器這個(gè)功能最好使)∽竞粒現(xiàn)在逐幀播放依许,注意視頻的上方有一個(gè)frame 時(shí)間戳。

一直往前直到你發(fā)現(xiàn)app圖標(biāo)高亮了為止缀蹄。這個(gè)時(shí)候系統(tǒng)已經(jīng)處理了圖標(biāo)上的點(diǎn)擊事件峭跳,開始啟動(dòng)app了,記錄下這一幀的時(shí)間缺前。繼續(xù)播放幀直到你看到了app整個(gè)UI的第一幀為止蛀醉。根據(jù)不同情況(是否有啟動(dòng)窗口,是否有啟動(dòng)畫面等等)衅码,

事件和窗口發(fā)生的實(shí)際順序可能會(huì)有不同拯刁。對(duì)于一個(gè)簡(jiǎn)單的app來(lái)說(shuō),你會(huì)首先見到啟動(dòng)窗口逝段,然后漸變出app真實(shí)的UI垛玻。在你看到UI上的任何內(nèi)容之后割捅,你應(yīng)該記錄下第一幀,這時(shí)app完成了布局和繪制帚桩,準(zhǔn)備開始顯示出來(lái)了亿驾。同時(shí)也記錄下這一幀所發(fā)生的時(shí)間。

現(xiàn)在把這兩個(gè)時(shí)間相減 ((UI displayed) - (icon tapped)); 得到app從點(diǎn)擊到繪制就緒的所有時(shí)間账嚎。雖然這個(gè)時(shí)間包含了進(jìn)程啟動(dòng)之前的時(shí)間颊乘,但是至少它可以用于跟其他app比較。

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

冷啟動(dòng)時(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布局

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

知道了Android冷啟動(dòng)時(shí)間的原理之后恳不,就可以通過(guò)一些小技巧來(lái)對(duì)冷啟動(dòng)時(shí)間進(jìn)行優(yōu)化檩小,從而讓你app加載變得”快“一些(視覺體驗(yàn)上的快)。我們可制作一個(gè)啟動(dòng)Activity的背景樣式的.9圖片烟勋,然后把這個(gè).9圖片做為windowBackground规求。

圖片制作好之后,我們就可以用它做為app冷啟動(dòng)階段的預(yù)覽元素卵惦,如下設(shè)置:

為啟動(dòng)的Activity自定義一個(gè)Theme

1

2

3

@drawable/window_background_statusbar_toolbar_tab

將新的Theme應(yīng)用到設(shè)置到AndroidManifest.xml中

1

2

3

4

5

6

7

8

9

android:name=".MainActivity"

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

由于給MainActivity設(shè)置了一個(gè)新的Theme阻肿,這樣做會(huì)覆蓋原來(lái)的Theme,所以在MainActivity中需要設(shè)置回原來(lái)的Theme

publicclassMainActivityextendsAppCompatActivity {

@OverrideprotectedvoidonCreate(Bundle savedInstanceState) {//Make sure this line comes before calling super.onCreate().setTheme(R.style.AppTheme);super.onCreate(savedInstanceState);

}

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末沮尿,一起剝皮案震驚了整個(gè)濱河市丛塌,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌畜疾,老刑警劉巖赴邻,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異啡捶,居然都是意外死亡姥敛,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門瞎暑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)彤敛,“玉大人,你說(shuō)我怎么就攤上這事了赌∧” “怎么了?”我有些...
    開封第一講書人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵揍拆,是天一觀的道長(zhǎng)渠概。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么播揪? 我笑而不...
    開封第一講書人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任贮喧,我火速辦了婚禮,結(jié)果婚禮上猪狈,老公的妹妹穿的比我還像新娘箱沦。我一直安慰自己,他們只是感情好雇庙,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開白布谓形。 她就那樣靜靜地躺著,像睡著了一般疆前。 火紅的嫁衣襯著肌膚如雪寒跳。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,182評(píng)論 1 299
  • 那天竹椒,我揣著相機(jī)與錄音童太,去河邊找鬼。 笑死胸完,一個(gè)胖子當(dāng)著我的面吹牛书释,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播赊窥,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼爆惧,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了锨能?” 一聲冷哼從身側(cè)響起扯再,我...
    開封第一講書人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎腹侣,沒想到半個(gè)月后叔收,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡傲隶,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了窃页。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片跺株。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖脖卖,靈堂內(nèi)的尸體忽然破棺而出乒省,到底是詐尸還是另有隱情,我是刑警寧澤畦木,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布袖扛,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏蛆封。R本人自食惡果不足惜唇礁,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望惨篱。 院中可真熱鬧盏筐,春花似錦、人聲如沸砸讳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)簿寂。三九已至漾抬,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間常遂,已是汗流浹背纳令。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留烈钞,地道東北人泊碑。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像毯欣,于是被迫代替她去往敵國(guó)和親馒过。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

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

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,077評(píng)論 25 707
  • 最近一直想整理一個(gè)關(guān)于Android熱啟動(dòng),冷啟動(dòng)的文章砚作,于是就有了下文(本文僅僅只是整理總結(jié)前人的知識(shí)點(diǎn))來(lái)源:...
    忘塵And閱讀 2,930評(píng)論 0 7
  • 【觸發(fā)背景】面對(duì)海量APP的今天窘奏,APP用戶量和活躍度成為評(píng)價(jià)一款A(yù)PP是否成功的重要因素。用戶下載APP后葫录,AP...
    siyu8023閱讀 10,316評(píng)論 1 14
  • 這是我的夢(mèng)境記錄者着裹。11.19 出來(lái)透氣的時(shí)候,欣然看見了那只小狗米同。 白色的骇扇,有點(diǎn)臟兮兮的,像是流浪了一段時(shí)間的樣...
    張企鵝閱讀 420評(píng)論 0 0
  • 擼起袖子加油干面粮,時(shí)刻不忘減肥要少孝! 新年登山享受太陽(yáng)的力量,太陽(yáng)賜予我力量吧熬苍! 早 中 晚 十年后重游丹霞山
    奔啵兒霸閱讀 289評(píng)論 0 0