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