“追蹤聖誕老人”— 每年最新API和應用開發技術的試驗田

谷歌開發者_發表於2017-03-14

640?wx_fmt=gif


640?wx_fmt=png


文 | Google 開發者專案工程師 Sam Stern


“追蹤聖誕老人”是 Google 的一個節日傳統。 除了在每個聖誕季給全球數以百萬計的使用者帶來歡樂之外,它還是每年最新 API 和應用開發技術的試驗田。 正因如此,我們每年都會在 Github 上釋出此應用的全部原始碼:

github.com/google/santa-tracker-android


2016 年,Santa 團隊挑戰自我,不僅為該應用引入新內容,還使它比以往更精簡、更高效。 在此文中,您可以閱讀到我們如何讓“追蹤聖誕老人”變得更精簡、更快速。


1. APK 的臃腫

經過多年的發展,“追蹤聖誕老人”已包含適用於多種遊戲和互動場景的視覺和音訊資源。 2015 年,“追蹤聖誕老人”APK 的大小為 66.1 MB。


Android Studio APK 分析器是一個非常有用的工具,可查明 2015 版應用如此龐大的原因。

640?wx_fmt=png


首先,儘管 APK 大小為 66.1 MB,但我們看到下載大小為 59.5 MB!其中資原始檔夾佔很大一部分,而資源和本機內容庫所佔比例也較大。


2016 版應用除了包含 2015 版應用的全部內容外,還新增了四款全新的遊戲。 最初,我們認為,新增這四款遊戲後,精簡此應用將是不可能完成的任務,但(注意,重點來了)2016 版應用的最終結果是:

640?wx_fmt=png


現在,儘管新增了四款遊戲和全新視覺效果,此應用的下載大小減少將近 10 MB。本部分的剩餘內容將探討我們是如何做到這一點的。


1)在 Google Play 上通過 APK 拆分實現多 APK 支援

2015 版應用增加了由 Google 的 Fun Propulsion Labs 團隊開發的“Snowdown”遊戲。 此遊戲使用 C++ 編寫,因此作為本機內容庫包含在“追蹤聖誕老人”中。 該團隊為我們提供了針對 armv5、armv7 和 x86 架構編譯的內容庫。 每個版本約為 3.5 MB,三者相加,即為您在 2015 版 APK 的 lib 條目中看到的 10.5 MB。


由於每臺裝置都只使用以上三種架構之一,因此可以刪除 2/3 的本機內容庫,以節省空間 — 對此,我們的折中方法是釋出多個 APK。 Android Gradle 構建系統原生支援為每種架構 (ABI) 構建一個 APK,它只需在應用的 build.gradle 檔案中插入幾行配置程式碼即可實現這一點:

640?wx_fmt=png


啟用拆分後,必須為每個拆分分配唯一的版本程式碼,以便它們可以在 Play 商店中共存:

640?wx_fmt=png


在最新版本的“追蹤聖誕老人”中,我們分別釋出了適用於 armv5、armv7 和 x86 的版本。 實施此次變更後,每個變體的本機內容庫從 10.5 MB 減少至 4 MB 左右,且未丟失任何功能。


2)優化圖片

“追蹤聖誕老人”APK 的大部分是影象資源。每款遊戲有數百個影象,每個影象有多種適合不同螢幕密度的尺寸。這些影象幾乎均為 PNG 格式,因此,過去幾年,我們通過對所有檔案執行 PNGCrush 來判斷作業是否已完成。 2016 年,我們瞭解到,PNG 無失真壓縮得到了很大改進,而 Google 的 zopfli 工具是目前最先進的壓縮工具。


通過對所有 PNG 資源執行 zopflipng,我們可將大多數影象無失真壓縮 10%,有些影象甚至可以壓縮多達 30%。其結果是,在不犧牲任何質量的情況下,使應用的大小縮減近 5 MB。例如,通過無失真壓縮,此聖誕老人影象由 10 KB 縮減至僅 7 KB。 不要費力去尋找不同之處,絕無不同之處的!


壓縮之前 (10.2KB)

壓縮之後 (7.4KB)

640?wx_fmt=png

640?wx_fmt=png


3)未使用的資源

在開發“追蹤聖誕老人”時,工程師們不斷重構此應用,增加和移除之前的邏輯和 UI 項。儘管程式碼稽核和 Lint 檢查有助於發現未使用的程式碼,但未使用的資源很有可能被遺漏。 而且,由於沒有針對資源的 ProGuard,我們的工具鏈無法幫助檢查資源,未使用的影象以及其他資源往往一不留神就混入應用中。


Android Studio 可以幫助查詢未使用、卻使 APK 變得臃腫的資源。 點選 Analyze > Run Inspection by Name > Unused Resources,Android Studio 將識別任何已知程式碼路徑未使用的資源。 必須首先刪除所有未使用的程式碼,因為死程式碼“佔用”的資源無法被識別為未使用。


使用有用的 Android Studio 工具進行幾輪分析後,我們得以發現數十個未使用的檔案,從應用中額外刪除了幾 MB 的資源。



2. 記憶體使用情況

“追蹤聖誕老人”風靡全球,其使用者使用的 Android 裝置多達數千種。 這些裝置當中很多都是幾年前的老產品,RAM 僅為 512 MB 甚至更小,因此,我們的遊戲之前曾出現過 OutOfMemoryErrors 錯誤。


儘管上述優化減少了 PNG 所佔用的磁碟空間,但在載入點陣圖 (Bitmaps) 時,它們的記憶體佔用情況並無改變。 由於“追蹤聖誕老人”中的每個遊戲均載入多個影象,記憶體使用量迅速達到危險水平。


在 2015 年,我們的十大崩潰事件中,有六起與記憶體有關。通過進行以下(和其他)優化,我們已將記憶體崩潰事件從十大崩潰事件中統統移出。


1)影象載入回退

在“追蹤聖誕老人”中啟動一個遊戲時,我們通常會將第一個場景所需的所有點陣圖載入至記憶體中,以便遊戲可以流暢執行。 原來採用的方法如下所示:

640?wx_fmt=png


然而,如果我們沒有足夠的 RAM 來將點陣圖載入至記憶體,decodeResource 函式將引發 OutOfMemoryError。 為避免出現此情況,我們在發現這些錯誤後嘗試使用更高的取樣率(每次以 2 倍取樣率遞增)重新載入所有影象:

640?wx_fmt=png


現在,使用此技術後,低記憶體裝置中圖形的畫素將更高,而且,通過這一折中方法,我們幾乎完全消除了由於載入點陣圖所導致的記憶體錯誤。


2)透明畫素

如上所述,影象在磁碟上的大小並不能很好地說明它的記憶體使用量。透明區域較大的影象就是一個明證。 PNG 可以將這些區域壓縮至接近零的磁碟大小,但每個透明畫素所需的 RAM 仍然不變。


例如,在“Dasher Dancer”遊戲中,動畫是通過一系列 1280x720 PNG 幀呈現的。 當動畫物件從螢幕中消失時,其中許多幀的大部分割槽域是透明的。 我們編寫了一個指令碼,將所有透明區域修剪掉,並記錄用於顯示每個幀的“偏移量”,這樣,總體顯示的畫素仍為 1280x720。在一項測試中,該指令碼將此遊戲執行時的 RAM 使用量減少了 60 MB!由於我們避免了將記憶體浪費在透明畫素上,因此較少需要縮小影象,並且可以在低記憶體裝置上使用更高解析度的影象。



3. 探索的其他途徑

除了上述重大優化外,我們還在應用精簡和加速方面探索了其他幾種途徑,取得了不同程度的效果。


1)啟動畫面

2015 版應用轉而採用 Material Design 的美學設計,通過中央的“卡片”列表啟動遊戲。我們發現,一半的遊戲會在啟動時導致卡片“波紋”效果反應遲鈍,但我們當時未能找到其根源所在,因而未能修復此問題。


在開發 2016 版應用時,我們力爭修復遊戲啟動慢的問題。經過數小時的調查研究,我們發現,只有固定為橫向螢幕的遊戲在啟動時才會出現遲鈍的問題。 而強制改變螢幕方向又帶來了掉幀問題。為打造更加流暢的使用者體驗,我們在啟動器 Activity 和遊戲 Activity 之間引入啟動畫面。 啟動畫面將檢測當前裝置螢幕方向以及開啟正在載入的遊戲所需的螢幕方向,並在執行時自動旋轉裝置,使之與遊戲設定的螢幕方向匹配。 這很快消除了遊戲啟動時任何明顯的反應遲鈍的問題,使整個應用的體驗更加流暢。


2)SVG

我們最初接手精簡資源的任務時,使用 SVG 影象似乎顯然是一個最佳方案。 向量影象要小得多,而且只需包含一次,即可支援多個螢幕密度。 由於“追蹤聖誕老人”採用“扁平化”的設計美學,我們甚至可以將多個 PNG 轉化為極小的 SVG,且質量損失較少。但是,在執行速度較慢的裝置上根本無法載入這些 SVG,其載入速度僅為 PNG 的數十分之一乃至數百分之一(具體取決於路徑複雜程度)。


最後,我們決定採納將向量影象大小限制在 200x200 dp 的建議,僅將 SVG 用於應用中的小圖示,而不用於較大的圖形或遊戲資源。



結論

640?wx_fmt=png


我們在開始構建 2016 版“追蹤聖誕老人”時,面臨一個非常棘手的問題:我們如何在增加新奇有趣的內容的同時,讓此應用變得更精簡,速度更快?通過不斷相互激勵,力求以更少的資源發揮更大的作用,並在做出每項變動時始終考慮資源限制因素,我們發現了以上優化措施。最終,我們得以使“追蹤聖誕老人”應用一如既往地正常執行……接下來我們的任務將是幫助 Claus 先生逐步降低所有附加 Cookie 所佔的比重。


推薦閱讀:

谷歌開源遊戲“Google追蹤聖誕老人”更新

Android Studio 2.3正式版釋出,官方全解析

讓Android支援內容庫保持最新

除了Material Design,Android Wear 2.0還有哪些看點?


640?wx_fmt=gif

相關文章