“追蹤聖誕老人”— 每年最新API和應用開發技術的試驗田
文 | 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 版應用如此龐大的原因。
首先,儘管 APK 大小為 66.1 MB,但我們看到下載大小為 59.5 MB!其中資原始檔夾佔很大一部分,而資源和本機內容庫所佔比例也較大。
2016 版應用除了包含 2015 版應用的全部內容外,還新增了四款全新的遊戲。 最初,我們認為,新增這四款遊戲後,精簡此應用將是不可能完成的任務,但(注意,重點來了)2016 版應用的最終結果是:
現在,儘管新增了四款遊戲和全新視覺效果,此應用的下載大小減少將近 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 檔案中插入幾行配置程式碼即可實現這一點:
啟用拆分後,必須為每個拆分分配唯一的版本程式碼,以便它們可以在 Play 商店中共存:
在最新版本的“追蹤聖誕老人”中,我們分別釋出了適用於 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) |
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)影象載入回退
在“追蹤聖誕老人”中啟動一個遊戲時,我們通常會將第一個場景所需的所有點陣圖載入至記憶體中,以便遊戲可以流暢執行。 原來採用的方法如下所示:
然而,如果我們沒有足夠的 RAM 來將點陣圖載入至記憶體,decodeResource 函式將引發 OutOfMemoryError。 為避免出現此情況,我們在發現這些錯誤後嘗試使用更高的取樣率(每次以 2 倍取樣率遞增)重新載入所有影象:
現在,使用此技術後,低記憶體裝置中圖形的畫素將更高,而且,通過這一折中方法,我們幾乎完全消除了由於載入點陣圖所導致的記憶體錯誤。
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 用於應用中的小圖示,而不用於較大的圖形或遊戲資源。
結論
我們在開始構建 2016 版“追蹤聖誕老人”時,面臨一個非常棘手的問題:我們如何在增加新奇有趣的內容的同時,讓此應用變得更精簡,速度更快?通過不斷相互激勵,力求以更少的資源發揮更大的作用,並在做出每項變動時始終考慮資源限制因素,我們發現了以上優化措施。最終,我們得以使“追蹤聖誕老人”應用一如既往地正常執行……接下來我們的任務將是幫助 Claus 先生逐步降低所有附加 Cookie 所佔的比重。
推薦閱讀:
除了Material Design,Android Wear 2.0還有哪些看點?
相關文章
- [譯] 谷歌尋蹤聖誕老人應用(Santa Tracker)遷移到 Android App Bundle 記錄谷歌AndroidAPP
- 聖誕快樂——Keras+樹莓派:用深度學習識別聖誕老人Keras樹莓派深度學習
- 假如聖誕老人學會用大資料派發禮物大資料
- 鏈路追蹤技術的應用及實踐
- 聖誕郵件營銷:如何做使用者眼中的聖誕老人?
- Surface Pro 3:聖誕老人給微軟的驚喜?微軟
- 索尼最新專利技術曝光:可用於VR領域的手部追蹤技術VR
- 視覺技術的聖盃:光線追蹤如何再現真實世界?視覺
- Java動態追蹤技術探究Java
- 淺談動態追蹤技術
- 分散式鏈路追蹤技術分散式
- 四種會話追蹤技術會話
- SQL追蹤和事件追蹤SQL事件
- Facebook收購VR技術公司 未來眼球追蹤應用VR頭盔VR
- RTX顯示卡實時光線追蹤技術解析 英偉達RTX顯示卡的光線追蹤技術是什麼?
- Node.js 應用全鏈路追蹤技術——[全鏈路資訊獲取]Node.js
- 「趣圖」第四張圖,程式設計師的聖誕節願望清單,過於真實,聖誕老人很難辦啊程式設計師
- 聖誕到了,發一個緣分測試軟體的分析。
- 最新的B/S開發技術 (轉)
- 最美聖誕樹!用Python畫棵雪夜聖誕樹送給你Python
- AsyncLocal<T>在鏈路追蹤中的應用
- Android 平臺的 10 款開源任務管理和時間追蹤應用Android
- 動態追蹤技術(中) - Dtrace、SystemTap、火焰圖
- 前沿探索|AI 在 API 開發測試中的應用AIAPI
- 聖誕鬧劇!阿里旗下開源專案聖誕彩蛋遭開發者狂批阿里
- 快到聖誕節了,用python來給自己的頭像加上一頂聖誕帽Python
- Flurry:聖誕節效應不再 應用下載增長放緩
- TGDC | 向陽而生 —— 光線追蹤的專案應用
- Jaeger鏈路追蹤在專案中的應用
- 追蹤應用程式所執行的sql語句SQL
- 追蹤時間的10個給力應用程式
- 牛!江蘇老人用AIoT技術管理千畝良田AI
- 光線追蹤往事:十年技術輪迴
- 全球快遞追蹤技術支援(Global Parcel Tracker Support)
- FOVE VR頭盔:支援紅外眼球追蹤技術VR
- 《我的世界》win10版將更新測試版本,首次支援光線追蹤技術Win10
- NVIDIA RTX賦力全球頂級應用,為百萬創意工作者提供光線追蹤和AI技術AI
- AIoT原生技術帶來更好的應用開發AI