眾所周知Android開機(jī)啟動速度較慢,于是如何加快啟動速度便成為一個值得討論的問題。
在查閱過許多資料后(特別是Google Group的android-platform),我整理總結(jié)出下面幾點(diǎn)基本看法。
Android開機(jī)啟動耗時較多的部分有2個,分別是preload classes和scan packages。
這里又?jǐn)?shù)preload classes最為耗時,在我的機(jī)子上一般需要13秒左右。實(shí)際上,在看過google group眾多關(guān)于preload class的主題后,基本可以確定以下事實(shí):
preloaded-classes list中預(yù)加載的類位于dalvik zygote進(jìn)程的heap中。在zygote衍生一個新的dalvik進(jìn)程后,新進(jìn)程只需加載heap中沒有預(yù)加載的類(這些后加載進(jìn)來的類成為該進(jìn)程所private獨(dú)有的),這樣便加快了應(yīng)用程序的啟動速度。實(shí)際上這是一種以空間換時間的辦法,因?yàn)閹缀鯖]有一個應(yīng)用程序能夠使用到所有的預(yù)加載類,必定有很多類對于該應(yīng)用程序來說是冗余的。但是也正如Google所說,智能手機(jī)開機(jī)遠(yuǎn)沒有啟動應(yīng)用程序頻繁——用戶開機(jī)一次,但直到下次再開機(jī)之前可能要運(yùn)行多個應(yīng)用程序。因此犧牲一點(diǎn)啟動時間來換取應(yīng)用程序加載時的較快速度是合算的。
preloaded-classes list已經(jīng)是Google Android工程師使用眾多測試工具分析,加以手動微調(diào)后形成的最優(yōu)化預(yù)加載列表,涵蓋了智能機(jī)上最長見的應(yīng)用類型所需要的各種類。很難想象我們自己能夠有什么手段能夠獲得比這樣更優(yōu)的一個預(yù)加載列表。所以,除非你的Android系統(tǒng)是被移植到非智能手機(jī)設(shè)備上使用(例如MID、EBOOK,可以不需要Telephony相關(guān)的類),不建議去“優(yōu)化”preloaded-classes list。
在zygote中單起一個線程來做preload,是否可行?答案是否定的。首先在zygote中不可以新開線程,其次,就算新開一個線程,在目前智能機(jī)硬件條件下(單核CPU),除非有頻繁大量的存儲IO,否則我們不能看到我們期望加速啟動效果。
關(guān)于scan packages的問題。同樣參考上面提到的那篇帖子,我們從中可以知道一個事實(shí):越少的apk安裝,越短的啟動時間。事實(shí)上確實(shí)如此,apk安裝的多少的確影響開機(jī)速度,但相比而言,scan packages所花費(fèi)的時間遠(yuǎn)沒有preload classe多。似乎這里沒有多少油水可榨,但起碼我們知道了:盡量減少產(chǎn)品中預(yù)置的apk數(shù)量可以提升啟動速度(哪怕精簡到極致也許只節(jié)省了2s)。
最后,關(guān)于那篇帖子中提到的start services階段,我認(rèn)為雖然此階段確實(shí)需要消耗可觀的時間,但是正如文中提到的那樣,優(yōu)化這些services其實(shí)就是剔除我們不需要的一些services,而且不僅僅是修改SystemServer.java的問題,任何使用到被優(yōu)化剔除掉的服務(wù)的代碼都必須加以修改,否則系統(tǒng)肯定是起不來的。這樣工作量大,而且難度也不小,并且有一定風(fēng)險。因此對這些services的優(yōu)化要慎之又慎。
那么加快啟動速度是不是就沒有辦法了呢?也不是。除了硬件上的改動,在軟件上使用BLCR技術(shù)也可以解決這個問題。
在此我認(rèn)為同時有必要提一下應(yīng)用程序啟動速度加速的問題。用過Android的都會發(fā)現(xiàn),第一次啟動某個應(yīng)用程序時比較慢,但只要不關(guān)機(jī)重啟,大部分情況下以后再次啟動就明顯的要快許多。因此我們很容易想到一種辦法,即“預(yù)加載”我們的應(yīng)用程序一次,那么下次用戶再次啟動我們時不就快了嗎?
我們首先明確一點(diǎn):任何“預(yù)加載”的想法都是不切實(shí)際的。先不討論實(shí)施在技術(shù)上的可能性,我們只要看一下Android的Activity生命周期管理就應(yīng)該明白,就算你通過某種方式“預(yù)加載”了你的某個Activity,你也不能確保在用戶真正要求開始運(yùn)行它的時候,你所“預(yù)加載”的Activity還存在,因?yàn)锳ndroid很可能在你為“預(yù)加載”第一次啟動Activity后的不久就將它gc掉了。依靠一個不可靠的技術(shù),顯然是不明智的。
那么還有沒有別的辦法呢?答案是有的,但是只在少數(shù)情況下才有一定意義。在源碼的frameworks/base/core/res/res/values/arrays.xml中,我們可以看到有名為“preloaded_drawables”的項(xiàng),其中列出的是Android在啟動時預(yù)加載的圖形資源,這樣在某個應(yīng)用程序需要這些圖形資源時就不必再加載了。如果我們某個應(yīng)用程序包含大量的圖形資源,那么我們可以將其加入到這個preloaded_drawables項(xiàng)中以加快我們應(yīng)用程序的啟動速度。但是這樣有一個顯而易見的弊端:同preload classes一樣,不是每個應(yīng)用程序都需要所有預(yù)加載的圖形資源,這些冗余的資源反而占據(jù)了應(yīng)用程序進(jìn)程的內(nèi)存空間。因此,這種技術(shù)實(shí)際應(yīng)用的局限性較大,僅限于這樣一種情況:某個設(shè)備只運(yùn)行固定的幾個應(yīng)用程序,而且這些應(yīng)用程序包含大量的圖形資源需要加載。但這樣會是一個什么設(shè)備呢?
好了,到此基本上把我這兩天研究的心得寫出來了。限于認(rèn)識水平有限,如果文中有誤或者哪位能有更好的想法,歡迎在下面留言:)如果以后我又有心得,會再更新此文。
-
Android
+關(guān)注
關(guān)注
12文章
3917瀏覽量
127037 -
啟動速度
+關(guān)注
關(guān)注
0文章
2瀏覽量
6584
發(fā)布評論請先 登錄
相關(guān)推薦
評論