Android啟動之冷啟動却盘,熱啟動

最近一直想整理一個關(guān)于Android熱啟動狰域,冷啟動的文章,于是就有了下文(本文僅僅只是整理總結(jié)前人的知識點)
來源:http://www.cnblogs.com/xunzhi/p/5794793.html
來源:http://blog.csdn.net/growing_tree/article/details/53183511
首先簡單說下這兩種啟動方式
冷啟動:
當(dāng)啟動應(yīng)用時谷炸,后臺沒有該應(yīng)用的進程北专,這時系統(tǒng)會重新創(chuàng)建一個新的進程分配給該應(yīng)用,這個啟動方式就是冷啟動旬陡,也就是先實例化Application拓颓。
熱啟動:
當(dāng)啟動應(yīng)用時,后臺已有該應(yīng)用的進程(例:按back鍵描孟、home鍵驶睦,應(yīng)用雖然會退出砰左,但是該應(yīng)用的進程是依然會保留在后臺,可進入任務(wù)列表查看)场航,所以在已有進程的情況下缠导,這種啟動會從已有的進程中來啟動應(yīng)用,也就是直接從進程中啟動,不需要重新創(chuàng)建Application溉痢,這個方式叫熱啟動僻造。

應(yīng)用的啟動過程

冷啟動啟動流程:當(dāng)點擊app的啟動圖標時,安卓系統(tǒng)會從Zygote進程中fork創(chuàng)建出一個新的進程分配給該應(yīng)用孩饼,之后會依次創(chuàng)建和初始化Application類髓削、創(chuàng)建MainActivity類、加載主題樣式Theme中的windowBackground等屬性設(shè)置給MainActivity以及配置Activity層級上的一些屬性镀娶、再inflate布局立膛、當(dāng)onCreate/onStart/onResume方法都走完了后最后才進行contentView的measure/layout/draw顯示在界面上,所以直到這里梯码,應(yīng)用的第一次啟動才算完成宝泵,這時候我們看到的界面也就是所說的第一幀。所以轩娶,總結(jié)一下儿奶,應(yīng)用的啟動流程如下:
Application的構(gòu)造器方法——>attachBaseContext()——>onCreate()——>Activity的構(gòu)造方法——>onCreate()——>配置主題中背景等屬性——>onStart()——>onResume()——>測量布局繪制顯示在界面上。
大致流程如下:
  1罢坝、點擊桌面圖標廓握,Launcher會啟動程序默認的Acticity,之后再按照程序的邏輯啟Activity
  2嘁酿、啟動Activity都需要借助應(yīng)用程序框架層的ActivityManagerService服務(wù)進程(Service也是由ActivityManagerService進程來啟動的)
    Step 1. 無論是通過Launcher來啟動Activity隙券,還是通過Activity內(nèi)部調(diào)用startActivity接口來啟動新的Activity,都通過Binder進程間通信進入到ActivityManagerService進程中闹司,并且調(diào)用ActivityManagerService.startActivity接口娱仔;
    Step 2. ActivityManagerService調(diào)用ActivityStack.startActivityMayWait來做準備要啟動的Activity的相關(guān)信息;
    Step 3. ActivityStack通知ApplicationThread要進行Activity啟動調(diào)度了游桩,這里的ApplicationThread代表的是調(diào)用ActivityManagerService.startActivity接口的進程牲迫,對于通過點擊應(yīng)用程序圖標的情景來說,這個進程就是Launcher了借卧,而對于通過在Activity內(nèi)部調(diào)用startActivity的情景來說盹憎,這個進程就是這個Activity所在的進程了;
    Step 4. ApplicationThread不執(zhí)行真正的啟動操作铐刘,它通過調(diào)用ActivityManagerService.activityPaused接口進入到ActivityManagerService進程中陪每,看看是否需要創(chuàng)建新的進程來啟動Activity;
    Step 5. 對于通過點擊應(yīng)用程序圖標來啟動Activity的情景來說,ActivityManagerService在這一步中檩禾,會調(diào)用startProcessLocked來創(chuàng)建一個新的進程挂签,而對于通過在Activity內(nèi)部調(diào)用startActivity來啟動新的Activity來說,這一步是不需要執(zhí)行的盼产,因為新的Activity就在原來的Activity所在的進程中進行啟動饵婆;
    Step 6. ActivityManagerServic調(diào)用ApplicationThread.scheduleLaunchActivity接口,通知相應(yīng)的進程執(zhí)行啟動Activity的操作戏售;
    Step 7. ApplicationThread把這個啟動Activity的操作轉(zhuǎn)發(fā)給ActivityThread侨核,ActivityThread通過ClassLoader導(dǎo)入相應(yīng)的Activity類,然后把它啟動起來蜈项。

冷啟動過程中碰到的白屏黑屏以及優(yōu)化啟動時間
  1芹关、白屏問題 :
  android studio升級 2.0之后 加上Instant Run续挟,Instant Run為了能夠讓我們快速部署代碼紧卒,背后其實是有一套非常復(fù)雜的邏輯的,比如要在APK中建立服務(wù)器與Android Studio進行通信诗祸,以及代碼差異比對和替換等跑芳,在研發(fā)過程中可能出現(xiàn)白屏問題,一般release版的程序是不會出現(xiàn)這種現(xiàn)象的直颅;如果接下來還會出現(xiàn)白屏問題博个,可以查看style文件
1<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> ...... <item name="android:windowIsTranslucent">true</item> <item name="android:windowNoTitle">true</item> </style>
  加入了兩個屬性,windowIsTranslucent和windowNoTitle功偿,將這兩個屬性都設(shè)置成true盆佣,就可以讓程序在初始化的時候窗口是透明的,初始化結(jié)束后程序主界面才會顯示出來械荷,從而也就完全看不到白屏界面了
2共耍、啟動時間的優(yōu)化
  先測量activity的啟動時間-------Activity的reportFullyDrawn()方法
 你就需要調(diào)用Activity的reportFullyDrawn()。它將在log里報告從apk初始化(和前面Displayed的時間是一樣的)到reportFullyDrawn() 方法被調(diào)用用了多長時間吨瞎。
reportFullyDrawn()方法顯示的log也是類似這樣:
ActivityManager: Displayed com.Android.myexample/.StartupTiming: +768ms
在4.4上調(diào)用reportFullyDrawn()方法會崩潰(但是log還是能正常打颖远怠),提示需要UPDATE_DEVICE_STATS權(quán)限 颤诀,但是這個權(quán)限只有系統(tǒng)app才能授權(quán)字旭。解決的辦法是這樣調(diào)
  try{
reportFullyDrawn();
}
catch(SecurityException e){}
  還有一種測量啟動時間的方法也值得一提,那就是screenrecord命令
  首先啟動帶—bugreport選項(它可以在frames 中添加時間戳-應(yīng)該是L中的特性)的screenrecord 命令:
  $ adb shell screenrecord --bugreport /sdcard/launch.mp4  然后點擊app的圖標崖叫,等待app顯示遗淳,ctrl-C screenrecord, 使用adb pull命令把文件導(dǎo)出到電腦。
  $ adb pull /sdcard/launch.mp4
  現(xiàn)在你可以打開錄制視頻看看發(fā)生了什么心傀。你需要一個能逐幀查看的視頻播放器(mac上的Quicktime 就可以屈暗,不清楚其它os上什么播放器這個功能最好使)。現(xiàn)在逐幀播放,注意視頻的上方有一個frame 時間戳恐锦。
  一直往前直到你發(fā)現(xiàn)app圖標高亮了為止往果。這個時候系統(tǒng)已經(jīng)處理了圖標上的點擊事件,開始啟動app了一铅,記錄下這一幀的時間陕贮。繼續(xù)播放幀直到你看到了app整個UI的第一幀為止。根據(jù)不同情況(是否有啟動窗口潘飘,是否有啟動畫面等等)肮之,
  事件和窗口發(fā)生的實際順序可能會有不同。對于一個簡單的app來說卜录,你會首先見到啟動窗口戈擒,然后漸變出app真實的UI。在你看到UI上的任何內(nèi)容之后艰毒,你應(yīng)該記錄下第一幀筐高,這時app完成了布局和繪制,準備開始顯示出來了丑瞧。同時也記錄下這一幀所發(fā)生的時間柑土。
  現(xiàn)在把這兩個時間相減 ((UI displayed) - (icon tapped)); 得到app從點擊到繪制就緒的所有時間。雖然這個時間包含了進程啟動之前的時間绊汹,但是至少它可以用于跟其他app比較稽屏。
 
Android冷啟動時間優(yōu)化
冷啟動時間是指當(dāng)用戶點擊你的app那一刻到系統(tǒng)調(diào)用Activity.onCreate()之間的時間段。在這個時間段內(nèi)西乖,WindowManager會先加載app主題樣式中的windowBackground做為app的預(yù)覽元素狐榔,然后再真正去加載activity的layout布局
冷啟動時間優(yōu)化
  知道了Android冷啟動時間的原理之后,就可以通過一些小技巧來對冷啟動時間進行優(yōu)化获雕,從而讓你app加載變得”快“一些(視覺體驗上的快)薄腻。我們可制作一個啟動Activity的背景樣式的.9圖片,然后把這個.9圖片做為windowBackground典鸡。
  
  圖片制作好之后被廓,我們就可以用它做為app冷啟動階段的預(yù)覽元素,如下設(shè)置:
為啟動的Activity自定義一個Theme
<style name="AppTheme.Launcher">
<item name="android:windowBackground">@drawable/window_background_statusbar_toolbar_tab</item>
</style>
將新的Theme應(yīng)用到設(shè)置到AndroidManifest.xml中
<activity
android:name=".MainActivity"
android:theme="@style/AppTheme.Launcher">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

由于給MainActivity設(shè)置了一個新的Theme萝玷,這樣做會覆蓋原來的Theme嫁乘,所以在MainActivity中需要設(shè)置回原來的Theme


復(fù)制代碼

public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { // Make sure this line comes before calling super.onCreate(). setTheme(R.style.AppTheme); super.onCreate(savedInstanceState); }}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市球碉,隨后出現(xiàn)的幾起案子蜓斧,更是在濱河造成了極大的恐慌,老刑警劉巖睁冬,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件挎春,死亡現(xiàn)場離奇詭異看疙,居然都是意外死亡,警方通過查閱死者的電腦和手機直奋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門能庆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人脚线,你說我怎么就攤上這事搁胆。” “怎么了邮绿?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵渠旁,是天一觀的道長。 經(jīng)常有香客問我船逮,道長顾腊,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任挖胃,我火速辦了婚禮杂靶,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘冠骄。我一直安慰自己伪煤,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布凛辣。 她就那樣靜靜地躺著,像睡著了一般职烧。 火紅的嫁衣襯著肌膚如雪扁誓。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天蚀之,我揣著相機與錄音蝗敢,去河邊找鬼。 笑死足删,一個胖子當(dāng)著我的面吹牛寿谴,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播失受,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼讶泰,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了拂到?” 一聲冷哼從身側(cè)響起痪署,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎兄旬,沒想到半個月后狼犯,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年悯森,在試婚紗的時候發(fā)現(xiàn)自己被綠了宋舷。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡瓢姻,死狀恐怖肥缔,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情汹来,我是刑警寧澤续膳,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站收班,受9級特大地震影響坟岔,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜摔桦,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一社付、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧邻耕,春花似錦鸥咖、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至御滩,卻和暖如春鸥拧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背削解。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工富弦, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人氛驮。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓腕柜,卻偏偏與公主長得像,于是被迫代替她去往敵國和親矫废。 傳聞我的和親對象是個殘疾皇子盏缤,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,781評論 2 354

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