淺談Android開機啓動速度優化(含應用程序啓動速度優化)

衆所周知Android開機啓動速度較慢,於是如何加快啓動速度便成爲一個值得討論的問題。

在查閱過許多資料後(特別是Google Group的android-platform),我整理總結出下面幾點基本看法。

 

Android開機啓動耗時較多的部分有2個,分別是preload classes和scan packages。

這裏又數preload classes最爲耗時,在我的機子上一般需要13秒左右。關於preload classes的優化,可以參見http://www.eoeandroid.com/thread-29953-1-1.html。這篇帖子並沒有給出如何優化preloaded-classes list的具體取捨。實際上,在看過google group衆多關於preload class的主題後,基本可以確定以下事實: 

  • preloaded-classes list中預加載的類位於dalvik zygote進程的heap中。在zygote衍生一個新的dalvik進程後,新進程只需加載heap中沒有預加載的類(這些後加載進來的類成爲該進程所private獨有的),這樣便加快了應用程序的啓動速度。實際上這是一種以空間換時間的辦法,因爲幾乎沒有一個應用程序能夠使用到所有的預加載類,必定有很多類對於該應用程序來說是冗餘的。但是也正如Google所說,智能手機開機遠沒有啓動應用程序頻繁——用戶開機一次,但直到下次再開機之前可能要運行多個應用程序。因此犧牲一點啓動時間來換取應用程序加載時的較快速度是合算的。
  • preloaded-classes list已經是Google Android工程師使用衆多測試工具分析,加以手動微調後形成的最優化預加載列表,涵蓋了智能機上最長見的應用類型所需要的各種類。很難想象我們自己能夠有什麼手段能夠獲得比這樣更優的一個預加載列表。所以,除非你的Android系統是被移植到非智能手機設備上使用(例如MID、EBOOK,可以不需要Telephony相關的類),不建議去“優化”preloaded-classes list。
  • 在zygote中單起一個線程來做preload,是否可行?答案是否定的。首先在zygote中不可以新開線程,其次,就算新開一個線程,在目前智能機硬件條件下(單核CPU),除非有頻繁大量的存儲IO,否則我們不能看到我們期望加速啓動效果。

關於scan packages的問題。同樣參考上面提到的那篇帖子,我們從中可以知道一個事實:越少的apk安裝,越短的啓動時間。事實上確實如此,apk安裝的多少的確影響開機速度,但相比而言,scan packages所花費的時間遠沒有preload classe多。似乎這裏沒有多少油水可榨,但起碼我們知道了:儘量減少產品中預置的apk數量可以提升啓動速度(哪怕精簡到極致也許只節省了2s)。

 

最後,關於那篇帖子中提到的start services階段,我認爲雖然此階段確實需要消耗可觀的時間,但是正如文中提到的那樣,優化這些services其實就是剔除我們不需要的一些services,而且不僅僅是修改SystemServer.java的問題,任何使用到被優化剔除掉的服務的代碼都必須加以修改,否則系統肯定是起不來的。這樣工作量大,而且難度也不小,並且有一定風險。因此對這些services的優化要慎之又慎。

 

那麼加快啓動速度是不是就沒有辦法了呢?也不是。除了硬件上的改動,在軟件上使用BLCR技術也可以解決這個問題。在http://blog.csdn.net/shuaiff/archive/2010/09/19/5894646.aspx這篇文章中比較詳細的介紹了BLCR技術在Android上的應用情況。個人認爲應用BLCR不復雜,值得我們嘗試。

 

 

在此我認爲同時有必要提一下應用程序啓動速度加速的問題。用過Android的都會發現,第一次啓動某個應用程序時比較慢,但只要不關機重啓,大部分情況下以後再次啓動就明顯的要快許多。因此我們很容易想到一種辦法,即“預加載”我們的應用程序一次,那麼下次用戶再次啓動我們時不就快了嗎?

 

我們首先明確一點:任何“預加載”的想法都是不切實際的。先不討論實施在技術上的可能性,我們只要看一下Android的Activity生命週期管理就應該明白,就算你通過某種方式“預加載”了你的某個Activity,你也不能確保在用戶真正要求開始運行它的時候,你所“預加載”的Activity還存在,因爲Android很可能在你爲“預加載”第一次啓動Activity後的不久就將它gc掉了。依靠一個不可靠的技術,顯然是不明智的。

 

那麼還有沒有別的辦法呢?答案是有的,但是隻在少數情況下才有一定意義。在源碼的frameworks/base/core/res/res/values/arrays.xml中,我們可以看到有名爲“preloaded_drawables”的項,其中列出的是Android在啓動時預加載的圖形資源,這樣在某個應用程序需要這些圖形資源時就不必再加載了。如果我們某個應用程序包含大量的圖形資源,那麼我們可以將其加入到這個preloaded_drawables項中以加快我們應用程序的啓動速度。但是這樣有一個顯而易見的弊端:同preload classes一樣,不是每個應用程序都需要所有預加載的圖形資源,這些冗餘的資源反而佔據了應用程序進程的內存空間。因此,這種技術實際應用的侷限性較大,僅限於這樣一種情況:某個設備只運行固定的幾個應用程序,而且這些應用程序包含大量的圖形資源需要加載。但這樣會是一個什麼設備呢?

 

好了,到此基本上把我這兩天研究的心得寫出來了。限於認識水平有限,如果文中有誤或者哪位能有更好的想法,歡迎在下面留言:)如果以後我又有心得,會再更新此文。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章