Google Developing for Android 一 - 相關上下文介紹

前幾天在G+上看到Google Developers站點,有一個Android系列的文章,分享到我的微博,週末閒來沒事就學寫了下,把它們簡單的翻譯了下,沒想到一發不可收拾,六篇文章所有都翻譯完了,有些地方省略了部分示例的描述或者換了另外一種表述,若是有理解的不許確的地方,還望指正android


原文:Developing for Android, I:Understanding the Mobile Context服務器

context或者這些建議爲什麼如此重要

對於理解這些最佳實踐的相關上下文是很是重要的。特別是明白移動端存在一些嚴重的限制,和臺式機以及服務器端的計算是徹底不一樣的。所以,在開發應用的時候,若是沒有將這些限制考慮進去,將會致使很大的性能問題和內存消耗,這不是針對於某一個應用而言,而是針對整個設備,由於不少擁有相同性能問題的app共同致使了一個性能不好的設備。
如下使一些重要的約束,限制和現實,在過去以及未來的移動設備中都很重要。網絡

移動設備的內存是頗有限的。固然不是指全部的設備,不過對於大多數的移動系統是這樣的。對於開發者來講,咱們使用的手機多是比大多數用戶如今或者未來所使用的設備更快更好,也更新。好比,擁有一個帶有 1GB-2GB內存Nexus 5對於咱們來講是比較合理的,512M的內存配置的手機在美國以及一些新興的低端市場是很常見的。所以,以2GB或者更大內存的標準去衡量一個App是不現實的。
明白Android會運行多個Activity和多個並行的Service也是很重要的。在最近App列表中切換而不是從新啓動一個App的方式對於創造出一種很好的體驗是很是重要的。可是這樣意味着若是這些app消耗了比它們本應該消耗的更多內存,那麼留給其它的應用的系統內存就不多了。若是這種低內存狀況發生,應用就不能保留在後臺,系統會幹掉app的進程,用戶就被迫以從新啓動的方式去開啓一個App,顯然這樣的體驗就比較差。app

即便最高級別的移動設備的CPU也要遠遠比臺式設備的CPU慢。固然即便你意識到了這一點,你也應該考慮那些大多數使用了比你更慢的CPU的用戶。適用於內存的建議也一樣適用於CPU:世界範圍的低端設備一直在售賣,所以不要以你本身相對較好的設備的性能爲基準,由於跑在那些大多數擁有較慢處理器和更低內存配置的設備上的差異是很是大的。
另外一個問題是,CPU的處理器是不會一直保持在最大的速度的。當系統認爲電池的發熱程度達到了臨界點的時候,就會致使CPU降頻。通常來講,這些狀況發生的時候用戶可能不會注意到,好比屏幕關閉了,或者輸入事件不響應了,或者動畫再也不運行了。降頻對App來講有兩層含意:(1)你的app可能在不少狀況降低低運轉速度,所以,即便是一個不錯的CPU,你也只可以獲取一個有限的速度 (2)你的app可能作了一些操做致使CPU沒法降頻,使得CPU始終維持在處理速度最大化的狀態(好比,頻繁,長時間或者無休止的動畫應該被避免,由於在動畫期間,爲了讓動畫更加流暢,系統將試圖以最大的功率來運行)。顯然,你不想去權衡較高的CPU速率和使用對下降電池的使用壽命的影響,所以當你不須要的時候,儘可能避免它們。ide

GPU性能的建議相似於CPU,固然還有些額外須要注意的地方:佈局

  • 上傳是消耗資源的
    在任何系統上上傳大大紋理(bitmap)都是比較消耗資源的,bitmap越大,操做時間越長。所以,這意味着頻繁大進行bitmap相關大圖形化操做會致使性能問題,好比bitmap,paths(會被光柵化到Bitmap中),和大量到新的或者不一樣的text(有種問題是大量的非英文的字符集合的致使的問題)性能

  • 咱們一般面臨的問題並非幾何的繪製,甚至一些紋理的繪製,而是大量的像素填充到高分辨率的設備上。這些高分辨率的屏幕會致使一個性能問題,由於在動畫某一幀中硬件不可以填充如此多的像素。比較常見的是過渡繪製,因爲重疊的內容,好比window背景,內容背景和一些半透明的View,就會致使應用會屢次重繪同一塊區域。測試

內存 == 性能

在這個系列中,不少的指導會圍繞着內存的使用來討論。但有一點很重要,就是內存是和運行期間的性能以及電池的壽命是牢牢關聯的。由於你分配的內存越多,設備就要爲你的應用作更多的工做。內存分配和回收增長了運行期間的活動會。大的heap內存意味着你的你的app佔用了更多的內存,可是設備整體的內存是減小了,會致使其它的活動被迫減小本身的內存開銷,或者直接被kill掉,這樣將致使設備的整體性能,由於用戶會在不一樣的活動中切換,而這些Activity須要從新啓動。更的的Heaps也會致使更長時間的GC中斷,由於一個較大的heap內存會致使內存的分配和回收消耗更長的時間。這些全部的行爲都會消耗更多的電量,由於設備所作的工做越多,電池就會消耗越多也更有限。優化

所以這個系列的文章不少涉及到了性能問題,事實就是這些技術對於寫出一個好的App來說,是很是重要的。動畫

所以這篇文檔的最佳實踐所涉及到的點不是內存就是性能,這些技術也是可以寫出一個好的app所必須的。

上面不少部分也提到,就是開發者所使用的設備可能比大多數將來使用者的設備都要好。雖然在2015年2GB已是主流,可是不少在世界範圍的不少新興市場仍然賣着512M的設備。

更平滑的幀率

對於Android的最佳體驗是低於16毫秒的幀率。也就是說應用必須在16毫秒內完成全部的輸入,佈局,繪製和其它全部的事情。這個速度容許系統在動畫和輸入事件的過程當中以60幀美妙的速度渲染。動畫必須能在60幀率的時間內完成必要部分的重繪已完成平滑的動效。問題更多的是,不少應用一般能夠在16ms內完成渲染,但它丟棄了當前幀,而且以後不可以延續以前的幀率,這種不連續的間隔會容易會引發用戶的注意。

平滑的完成一幀意味着任何特殊的幀須要執行全部的渲染代碼(包括framework發送給GPU和CPU繪製到緩衝區的命令)都要在16ms內完成。這也就是爲何即便在垃圾回收事件中丟失了5ms也會有很大的影響。由於它嚴重限制了一幀時間內剩餘的繪製時間。越接近16ms,在垃圾回收事件觸發的時候,就越容易致使卡頓。

緩衝區只可以在

有兩個運行環境須要主要:Dalvik和ART。在5.0版本以前,Android使用Dalvik。開發者能夠在4.4版本中選擇ART進行測試。可是它只會在5.0的系統中運行。

Dalvik是採用的時 JIT編譯器,可以執行一些細微的優化,可是和其它的不少JIT編譯器是不一樣的。ART是一個Ahead-of-Time 編譯器,比Dalvik會作更多的優化。然而,不管是Dalvik仍是ART提供的優化水平與服務器和臺式機運行平臺都是不同的。好比方法的內聯和escape analysis。有一些內聯,ART會在葉子方法上執行,可是更進一步的優化只可能在未來的版本中出現,由於將來會有新的優化編譯器。因爲app開發者可能須要支持老得版本,他們須要繼續關心如今和以前編譯器的限制。

一般,ART性能要比Dalvik提高30 - 200+%。ART的編譯器會執行更多的優化,好比,實質性的提高接口的分發。ART優化的範圍要更大些,內存分配也更快。最終,應用的線程會更少的受限於垃圾回收,短期的中斷次數也會減小。

垃圾回收器

垃圾回收器是一個經過運行期間釋放那些再也不引用的內存的過程。GC也是致使嚴重性能問題的緣由之一,若是GC所作的工做超過了那些必須的工做,那麼留給應用平滑的幀率的時間就越少。

在Dalvik和ART中的垃圾回收器實質上是不一樣的。一個主要的區別就是Dalvik不是一個移動的回收器。就是說全部的分配對象都將呆在Heap的同一個地方,這對於Dalvik來講,爲新的對象找到可分配的內存就會更加困難和耗時,特別是當Heap顆粒化和碎片化而且又有大量對象急需內存的時候。Heap碎片化也會致使GC更頻繁的中斷,由於Dalvik會嘗試清理從那些無用的heap。這些GC中斷是很是消耗資源的,而且在正常的狀況下一個比較快的手機也會很容易耗費掉10-20ms的時間。很重要的是,垃圾回收的時間與在堆中對象的數量成正比,這是儘量避免分配對象的另外一個緣由。

ART會動態的提高垃圾回收的效率。好比,ART是一個移動的垃圾回收器,在應用長時間單停止時,它會讓heap變得緊湊而不會影響用戶的體驗。並且,這裏有一些獨立的專門用於大對象的heap,好比像bitmap這樣的對象,ART就會更快的找到內存,而不是有序的遍歷碎片化的heap。在ART中的中斷,一般在2-3ms間。

儘管ART相對於Dalvik來講的垃圾回收來講有一個很大的性能提高。可是在寫Android app的時候,仍然須要注意的是即便是2-3ms的時間對於超過16ms幀率的界限也是足夠的。所以,儘管垃圾回收在5.0以後再也不是耗資源的行爲,但也是始終須要儘量避免的,特別是在執行動畫的狀況下,可能會致使一些讓用戶明顯感受的丟幀。

UI Thread

不少的性能和卡頓問題是因爲咱們在UI線程中作了大量的工做。Android是一個獨立線程的UI系統,在這裏全部發生在View上的操做,包括View的繪製,都發生在Activity的UI線程上。任何發生在相同UI線程的操做,即便是View的繪製也可能致使卡頓,由於它沒有時間在16ms的時間內達到一個平滑的幀率。

在5.0版本里,framework引入了「Render Thread」,用於向GPU發送實際渲染的操做。這個線程減輕了一些UI Thread減小的操做。可是輸入,滾動和動畫仍然在UI thread,由於thread必須可以響應操做。

存儲的指標在不一樣的Android設備上是不一樣的,可是多是比較慢並且是受限制的。移動設備只有8G(2015年,在低於中等水平的設備中很常見)甚至4G搭配一個SDcard,去存儲整個系統,全部的應用以及全部的音頻,很容易就滿了。在這種狀況下,一個app可能致使用戶爲它刪除其它內容以便獲取更多空間,或者由於每有足夠的空間就直接卸載它。

存儲性能也是須要關心的點。移動設備和桌面設備的硬盤相比是徹底不一樣的。

同時,也要注意到外部存儲SDcard的內存在I/O性能上可能有很大的不肯定性,其依賴於供應商,芯片和速度指標。可是App不該該阻止用戶使用SDcard,由於不少設備確實內存比較小,須要它做爲擴展。

位於在城市中的大多數軟件開發者來講擁有一些現代的基礎設施和移動網絡是很簡單的。但不少其它地區並不具有這樣的設施。更別說LTE或4G了。不少國家的地區仍是2G的網絡並且可能還要承受大量數據的傳輸。這樣就會致使兩個通用的問題:

  • 依賴於快速的網絡速度
    App嚴重依賴大媒體數據(Video,audio,images)在網絡基礎較差的地方可能沒有選擇。可是避免下載,直到條件容許的狀況下再去下載也是App體驗的一部分

  • 多度同步
    也許你的App但願更新一些信息,可是用戶並不須要它,更重要的問題,設備並不該該承受全部應用程序與網絡不斷交互的狀況。這種動態會很容易地使設備持續工做而不可以進行休眠,最終影響電池的續航。

每個設備都是一個村落

用戶的設備上會安裝不少的應用,包括系統的UI和Launcher App。若是你的App使用了越多的資源(內存,CPU,GPU,電池),那麼其它應用就會越少,那麼呈現給的用戶的設備就會越差。若是你的處理越多,當系統須要更多內存的時候,就越有可能試圖從內存中幹掉它,那就意味着你的App就要花費更長時間去開啓,從而致使一種很很差的體驗。

所以,在Android設備上成爲一個良好的公民吧。也是每一個App應該去作的,由於若是每一個應用都貪婪,那麼最終痛苦是設備和用戶。

平民的災難

移動設備最大的問題是一些app在本身感興趣的狀況下活動致使了設備的總體性能和體驗。分析特定app可能不是應用須要修復的標誌性的問題。可是對設備總體的影響,全部的app都遭受資源的限制,最終用戶的體驗不好。

一個好的例子是觀察某個應用是否太頻繁的同步。那意味着特定的應用在以特定的頻率訪問服務器。可是若是用戶有超過100個應用都在這樣作,相比較那些延遲,批處理的同步系統來講,結果就是設備將永遠不可以休眠而且很快耗完電。

相關文章
相關標籤/搜索