Android卡頓千古謎案全面解析
有沒有感覺你用的Android手機很卡?貌似手機配置都已經(jīng)挺不錯的了,四核、八核、≥2GB RAM這樣的配置居然還會發(fā)生動畫掉幀、點擊某個按鈕或圖標(biāo)出現(xiàn)停頓一會兒之類的情況?高通、MTK、英偉達(dá)之類的芯片制造商不是整天宣稱什么制程、架構(gòu) 如何先進(jìn),什么一秒鐘多少萬多少億次浮點運算,怎么還整天被iPhone用戶嘲笑很卡很不爽?
本文引用地址:http://cafeforensic.com/article/277680.htm關(guān)于Android系統(tǒng)存在卡頓和不流暢的問題,似乎是個千古謎案——即便到現(xiàn)在也還有很多Android用戶堅持說他們新買的旗艦已如絲般柔滑,卻真正在流暢的細(xì)微處比iOS差了一截。不過從古到今,試圖解釋Android卡頓的觀點就有千百種,據(jù)說即便是采訪Android內(nèi)部開發(fā)工程師,他們也說這是個說不清道不明的問題。這次我們就從相關(guān)Android卡頓的幾個主流說法談起,嘗試從相對淺顯的角度來理解這一問題。
都是Dalvik VM虛擬機惹的禍?
按照普通人對虛擬機的理解,就是平常一直在用Windows操作系統(tǒng),想裝個Mac OS玩玩又沒錢買蘋果電腦咋辦?——裝個虛擬機。從這個角度來理解,不管是出于玩機還是開發(fā)、或考慮兼容性的問題,用過虛擬機的同學(xué)就知道,這東西的效率 和原生安裝方式不在一個層面,不管是從驅(qū)動、資源利用等各角度來看都是如此。
Android的系統(tǒng)框架上,在最底層的Linux內(nèi)核之上就跑了個虛擬機,在Android 4.4之前,這個虛擬機叫Dalvik VM。絕大部分Android應(yīng)用就運轉(zhuǎn)在Dalvik VM虛擬機之上——很多人,甚至是程序員認(rèn)為,Android系統(tǒng)之所以不流暢和卡頓,罪魁禍?zhǔn)拙褪谴颂摂M機,想想我們平常應(yīng)用層面虛擬機的運行效率就知 道了,再牛逼的硬件也抵不住軟件這么坑啊。
早年的Android系統(tǒng)能有如此奇葩的框架和執(zhí)行思路并不是因為Andy Rubin真的很二。Android選擇這條路的原因是看中互聯(lián)網(wǎng)上浩瀚的Java資源——Java應(yīng)用可以運行在Android這種Linux內(nèi)核的系 統(tǒng)上正是拜虛擬機所賜,對于一個當(dāng)時的新生系統(tǒng)而言,想要盡早構(gòu)建起應(yīng)用生態(tài),這是個捷徑——也是Android現(xiàn)在擁有這么多應(yīng)用資源的關(guān)鍵所在(雖然 蘋果就沒這么做)。
不過另有一個幫派的程序員表示,這個層面的虛擬機和我們平常自己在電腦上裝的虛擬機根本不是一回事,它的執(zhí)行效率并沒有人們想象的不堪,實際使用中和直接調(diào)用底層基礎(chǔ)函數(shù)也沒差多少。
(NDK的也可是讓Android應(yīng)用不用跑在虛擬機上)
我們從谷歌后來的行動看到,情況好像沒有這么簡單。早在Android 2.3時期,谷歌就意識到Dalvik并非長久之計,就為Android引入了NDK——這是個真正的開發(fā)包,使用C/C++語言也可以為Android 開發(fā)應(yīng)用,以這種方式開發(fā)的應(yīng)用不會跑在虛擬機上。彼時的程序員認(rèn)為,這是Android從應(yīng)用層真正開始具備與iOS相抗衡實力的開始,但這種夢想很快 就被打破,一方面是讓開發(fā)者放棄Java全面轉(zhuǎn)向C/C++并不現(xiàn)實,而且后兩者開發(fā)難度甚高,涉及內(nèi)存操作甚至與設(shè)備驅(qū)動程序?qū)υ?,對于Android 這種機器種類繁多的系統(tǒng)而言,開發(fā)者采用NDK很不現(xiàn)實(類似《極品飛車》這種大型3D游戲運行代碼理應(yīng)采用C++,所以這類游戲針對Android手機 的不同處理器甚至還有不同的版本)。
所以在Android 4.4時期,谷歌為之引入了一種新的ART虛擬機,用以替代Dalvik。ART的特點是相比Dalvik更為高效:Dalvik虛擬機在每次運行應(yīng)用時 會將之編譯為二進(jìn)制機器代碼,ART的改進(jìn)之一就在于在應(yīng)用安裝的時候就將二進(jìn)制代碼編譯完成(所以每個應(yīng)用安裝所占空間會更大),這叫預(yù)編譯模式,而不 是等到每次運行應(yīng)用才編譯。
理論上聽來,ART似乎的確較Dalvik效率更高些,谷歌自己說ART對比Dalvik速度平均提升幅度達(dá)到80%,不過各位已經(jīng)在用 Android 4.4甚至5.0的小伙伴有這種體會嗎?或許今后隨著Android生態(tài)以及系統(tǒng)自身的完善,ART可以表現(xiàn)出更大的優(yōu)勢,起碼現(xiàn)在我們沒怎么看出來它對 系統(tǒng)流暢性體驗改善有多大貢獻(xiàn)。
另外,在系統(tǒng)框架層面,除了探討虛擬機可能是拖垮Android流暢性的元兇之一這種說法,還有人也會談到Linux這類宏內(nèi)核在驅(qū)動方面的先天不足,這些或許都是阻礙Android有絲般流暢的要素,但是否還有其他原因呢?
硬件加速弱爆了
顯示系統(tǒng)圖形界面的時候,如果畫圖的工作都交給CPU完成,這效率是可想而知的,猶如你讓一位精通數(shù)學(xué)的同學(xué)畫圖,多少他倒是能畫,只是能不能畫好 很成問題。如果GPU,也就是專門的畫圖工作者能夠協(xié)助這個過程,情況自是大不相同。雖說系統(tǒng)流暢性是個相當(dāng)大的話題,但硬件加速是否做得好就成為其中的 重要因素。
完善如上所述的這個過程,幾乎是貫穿Android 2.x早期,到最新的Android 5.1,甚至此后很長一段時間內(nèi),谷歌需要努力的方向。針對系統(tǒng)圖片、網(wǎng)頁等2D圖形繪制,Android所用的是谷歌早在2005年就收購的 Skia(那時Android都還沒出生,Chrome也采用Skia作為2D圖形引擎)。
Skia原始版本的圖形光柵處理完全基于CPU和軟件運算,也就是說早期Android的2D圖形繪制對GPU的利用率存在嚴(yán)重不足,相較iOS和Windows Phone這種在硬件加速領(lǐng)域有著很久積累的系統(tǒng)完全不是一個水平。
在Android的系統(tǒng)設(shè)置-調(diào)試選項中,有個“強制進(jìn)行GPU渲染”選項,開啟這個選項以后會發(fā)現(xiàn)某些應(yīng)用的運行的確更流暢了,但有些則出現(xiàn)了更 糟糕的使用體驗。在Android 2.3時代,國外科技博客DorothyBrowse特別強制開啟這種Skia GPU加速,嘗試進(jìn)行Webkit渲染(Chrome的渲染引擎)測試,結(jié)果發(fā)現(xiàn)相較CPU自己畫圖,所謂的GPU加速居然出現(xiàn)了反效果,可知當(dāng)時的 Skia GPU加速在Android平臺有多么不成熟。
在Android 3.0之前,這套系統(tǒng)都沒有真正行之有效的圖形加速方案(即便從初版開始,Android就在努力融合硬件加速),Android 3.0才實現(xiàn)窗口相對完整的硬件加速繪制。實際上,即便是到Android 4.1,谷歌大肆宣傳的黃油計劃,過渡動畫幀率達(dá)到60fps,通過預(yù)判和緩沖來提升效率,其GPU加速支持也并不完整。谷歌自己的官方文檔中就提到,并 不是所有2D圖像操作的API都已經(jīng)支持硬件加速。
不過總的說來,Android的GPU加速是朝著逐步完善的方向發(fā)展的,最新版相較過去已經(jīng)有了很大程度的提升,從系統(tǒng)級應(yīng)用和各類操作這些年來流 暢度的明確提升就能感覺得到,即便這種提升在iOS和Windows Phone面前還是顯得有些無力。可是來到第三方應(yīng)用,這個問題又變得非常復(fù)雜。
第三方應(yīng)用質(zhì)量很悲劇
在宣稱如“絲般順滑”、甚至“趕超iOS”的Android 4.1問世以后,不說和iOS比實際如何,其系統(tǒng)級應(yīng)用倒真的流暢了很多,可是第三方應(yīng)用死性未改,該怎么卡還是怎么卡。這就是個相當(dāng)復(fù)雜的問題了。
其一,在Android一步步向前的步伐中,API Level越高,GPU硬件加速也的確愈加完善,比如Android 5.1所用API Level 22。所謂的API Level,標(biāo)識的是Android平臺框架的API版本。這個API可以理解為Android所跑虛擬機針對應(yīng)用開發(fā)而支持的功能,隨著版本號的變化, 這些“功能”在發(fā)生著升級或轉(zhuǎn)變。對Android的系統(tǒng)應(yīng)用而言,采用最新的API是理所當(dāng)然的,流暢性也保持在最佳狀態(tài)。
但對第三方應(yīng)用來說,采用最新的API,就意味著對舊版本系統(tǒng)的拋棄。比如微信應(yīng)用更新,如果很任性地用上API Level 22,那么最新版的微信將只支持Android 5.1,人類可以忍受嗎?所以微信迄今為止還在采用API Level 9,微博則為API Level 14。這種API的迭代,也是蘋果為何高度追求系統(tǒng)一致性的重要原因。想想Android系統(tǒng)的碎片化問題,第三方應(yīng)用要變得更高效,好像是個根本無法完 成的任務(wù)。
這還只是第三方應(yīng)用開發(fā)的一環(huán)。其二,Android應(yīng)用開發(fā)者的“隨性”讓Android應(yīng)用的效率更加悲慘。比如說谷歌在應(yīng)用開發(fā)的指導(dǎo)原則中提到,如果應(yīng)用不夠流暢,應(yīng)該看看是否存在“過度渲染(OverDraw)”的問題,就是布局重疊、重復(fù)繪制。
要檢查這個問題,有興趣的同學(xué)可以一起來做這個實驗。在Android系統(tǒng)設(shè)置的開發(fā)者選項中,選擇“顯示GPU過度繪制”,此時整個界面變得花花 綠綠一片。這些色塊所表達(dá)的是,無色透明狀態(tài)為最佳,藍(lán)色表示很好,綠色為不錯,淺紅色表示較差,深紅色為過度繪制問題嚴(yán)重。類似Instagram等應(yīng) 用的情況似乎挺好,而某博和Facebook過度渲染的問題就很嚴(yán)重。這只是Android應(yīng)用開發(fā)中的一個例子,如此這般罔顧開發(fā)原則的狀況那是數(shù)也數(shù) 不清的。在Android相對開放的應(yīng)用世界中,這種情況是不會有警察去抓的,顯然iOS全程把關(guān)App Store就不會這么悲劇。
其三,在天朝這樣一個奇特的國度,開放的系統(tǒng)無疑為許多應(yīng)用開發(fā)商提供了大好機會。很多應(yīng)用當(dāng)安裝到你手機中,其行為習(xí)慣可能是你完全不知道了,而且可能實情會更令你震驚,這就是下面一個話題了。
內(nèi)存居然還不夠用?裝越多APP手機越卡
相關(guān)Android裝越多應(yīng)用,手機越卡的解釋非常多樣,甚至包括對于固態(tài)存儲原理的解釋。或許這些都是原因所在,不過更關(guān)鍵的原因是這樣 的:Android系統(tǒng)中有個叫做Receiver(接收器?)的東西,負(fù)責(zé)傳遞系統(tǒng)接收到的變化,就像是神經(jīng)系統(tǒng)。比如說按下Power鍵鎖屏,長按關(guān) 機,或者長按相機按鍵啟動相機應(yīng)用,或者插入耳機,都是在Receiver接收到以后通知相應(yīng)apk,后由程序給出響應(yīng)。
應(yīng)用本身就可以跟系統(tǒng)注冊任何形式的Receiver,其較大的用處之一是通知系統(tǒng)啟動某個程序。比如YouTube的Receiver在開機時、 系統(tǒng)語言切換后、系統(tǒng)賬戶改變后這三種情況下自動啟動YouTube應(yīng)用本身——這是個比較常見的Receiver。而國內(nèi)的諸多“異士”是如何寫 Receiver的呢?
某些著名視頻站APP在下面這些情況下都會啟動,包含開機時、網(wǎng)絡(luò)狀況改變時(2G、3G與WiFi間切換)、安裝其它App時、卸載其它APP 時、用戶喚醒機器時.。。對于用戶而言,無論你怎么殺進(jìn)程清內(nèi)存,只要這些操作被觸發(fā),Receiver就會啟動相應(yīng)程序,話說連個WiFi、下個新應(yīng)用 都要啟動該應(yīng)用,哪有透明度可言,真是獨有社會主義特色。
此類國產(chǎn)APP相當(dāng)多見,常見Receiver動作還有:耳機拔出或插入時、文件下載完成后、WiFi掃描SSID完成后,都啟動程序,是不是感覺 灰常神奇?它們的宗旨就是永遠(yuǎn)不會被你殺死,什么一鍵殺進(jìn)程,分分鐘給你活過來,除非徹底卸載它們,或禁用相應(yīng)Reciever。在這種情況 下,Android系統(tǒng)對于內(nèi)存容量的要求自然是非一般的。
所謂的內(nèi)存回收機制此刻都已不值一提,何以iPhone 1GB內(nèi)存流暢運行至今,而Android現(xiàn)如今已是3GB時代;這也是很多Android優(yōu)化文章告訴用戶,如果某應(yīng)用一周不用就卸載的核心所在,環(huán)境使然。你聽說過iOS優(yōu)化讓用戶卸應(yīng)用的嗎?
碎片化問題讓Android千瘡百孔
可以說,除了Android本身的頑疾之外,導(dǎo)致上述絕大部分問題的根源就是Android的碎片化,無論是Android自身開放的態(tài)度讓各種高 配、低配的手機都在使用,還是手機制造商對Android進(jìn)行的二次開發(fā)。要將硬件加速做好、規(guī)范第三方應(yīng)用質(zhì)量,在Android開放的理念下是幾近不 可能完成的任務(wù),且谷歌自己都難以收拾局面。
Android的開放和碎片化帶來的問題還遠(yuǎn)不止上面這些,一個典型的例子是iOS和Windows Phone都具備了特別出色的信息推送機制,比如說QQ、微信接收消息,在iOS和Windows Phone中,應(yīng)用本身不需要常駐后臺,通過每臺手機和推送服務(wù)器保持唯一連接,就能收到推送通知,無論對性能和功耗的節(jié)省都具備了極大的意義。
Android系統(tǒng)當(dāng)然也具備了消息推送的可行性,但由于碎片化問題,以及國內(nèi)因為某種原因不得不去掉谷歌服務(wù)的現(xiàn)狀,令A(yù)ndroid不同應(yīng)用采 用五花八門的推送機制。許多Android應(yīng)用獲取消息的方式是輪詢(而非推送),即應(yīng)用主動地與服務(wù)器連接并查詢是否有新消息,可想而知它對系統(tǒng)和網(wǎng)絡(luò) 資源的消耗。
關(guān)乎Android系統(tǒng)本身,則除了文首提到的虛擬機機制,還有許多相當(dāng)微妙的問題形成它與iOS之間的流暢性差異,比如Android對多任務(wù)的 支持更類似于桌面系統(tǒng),本身就只有靠堆砌硬件才能滿足這種多任務(wù)的需求,當(dāng)然iOS的多任務(wù)也已經(jīng)不像很多人理解的那樣,是多年前的“假后臺”了,它針對 第三方應(yīng)用開放的多任務(wù)API正越來越多。
總之,Android的卡頓和不流暢是個極其復(fù)雜、龐大的問題,上面所提的這些也只是挖掘了其中的一部分。就Android系統(tǒng)的發(fā)展軌跡來看,從 初代問世至今,其發(fā)展史都可以看做是谷歌在系統(tǒng)流暢性問題上所做的一次次努力,流暢性改善甚至是Android前行的一條線索,所以谷歌也才毫不吝嗇地一 次次地宣傳,我們的系統(tǒng)更流暢了,不管相較競爭對手有多大差距和多少不可控性,現(xiàn)在的Android也已經(jīng)比過去流暢了很多,雖然未來還有很長的路要走。
linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)
可控硅相關(guān)文章:可控硅工作原理
linux相關(guān)文章:linux教程
比較器相關(guān)文章:比較器工作原理
c++相關(guān)文章:c++教程
加速度計相關(guān)文章:加速度計原理
評論