Android 開發者減少 APK 文件大小的提示
已發表: 2015-10-281) ProGuard
諸如 ProGuard 之類的代碼壓縮工具將顯著減小 APK 文件的大小。 該工具可在 sourceforge 獲得。 請注意,在應用 ProGuard 後重新測試所有應用程序非常重要,因為它有時可能會改變應用程序的行為。 由於 ProGuard 替換了應用程序符號,為了使代碼難以閱讀,保留符號映射非常重要,以便在必須調查應用程序中的崩潰時可以將堆棧跟踪轉換回原始符號。
2) 去除Debug信息
我建議您從應用程序中刪除所有與調試相關的功能。 應用程序一般不會看到或使用這些數據,Android 操作系統也不需要它來運行應用程序。 因此,調試信息只會浪費空間,應該刪除。
為此,所有與調試相關的功能都必須包含在條件塊中,如下所示:
靜態最終調試=假; 如果(調試){ v(標籤,“調試……”) }
重要的是在編譯時設置調試標誌(即聲明為靜態最終),以便編譯器能夠完全刪除所有調試功能。 創建您自己的調試方法(如下所示)並不是一個好主意,因為對 myDebugPrint() 的調用沒有包含在條件塊中,這意味著編譯器必須在調用類中保留有關 myDebugPrint() 的信息。
公共無效 myDebugPrint() 如果(調試) v(標籤,“調試……”); } } … 我的調試打印()
3) 從本機庫中刪除調試符號如果您的應用程序仍在開發中並且仍需要調試,則使用調試符號是有意義的。 但是,如果在編譯發布版本時仍然出現調試符號,並且如果您想刪除它們,那麼我們建議從本機庫(.so 文件)中刪除調試符號。 這是使用 Android NDK 中的 arm-eabi-strip 命令完成的。
4)推薦的媒體格式如果您的應用程序嚴重依賴圖像、音頻或視頻,另一種減少 APK 文件大小的方法是使用某些媒體格式。 我們建議您對圖像、音頻和視頻使用以下媒體格式:
- 視頻:使用 H264 AVC。 將視頻編碼為不大於目標設備屏幕分辨率(如果已知)的分辨率。
- 音頻:建議所有音頻資源使用 AAC 音頻。 與 mp3 或 Ogg Vorbis 相比,AAC 在給定質量下實現了更好的壓縮。 絕不應使用 WAV 等原始格式。 使用 WAV 格式的常見原因是解碼壓縮音頻流通常意味著播放時的高延遲。 但是,Android 提供了 Sound Pool API,它使應用程序能夠使用壓縮的音頻流而不會造成高延遲。
- 圖像:PNG 或 JPEG。 使用 PNG; 由於它是一種無損格式,因此非常適合紋理和藝術品,因為壓縮不會產生視覺偽影。 如果有空間限制,請使用 JPEG 或 PNG 和 JPEG 的組合。 高質量的 JPEG 圖像可能適用於大型逼真的圖像,JPEG 壓縮方案已針對這些圖像進行了優化。
- 在不損失質量的情況下優化 PNG 尺寸
如果您使用 PNG 格式,PNG 圖像可以減小文件大小而不會損失質量。 為此,請使用 OptiPNG 或 PNGCrush 等工具。 兩者都非常適合減少 PNG 文件的大小,同時仍能確保圖像質量。 PNGcrush 是一個開源程序,它迭代 PNG 過濾器和 zlib (Deflate) 參數,使用每個參數配置重複壓縮圖像,並選擇產生最小壓縮 (IDAT) 輸出的配置。 另一方面,OptiPNG 完全在內存中執行試驗,並且只將最終輸出文件寫入磁盤。 此外,它還為用戶提供了多種優化預設。
5) 刪除未使用的資源另一個需要考慮從 APK 文件中刪除的潛在空間浪費是 res 目錄中未使用的資源,例如未使用的佈局、可繪製對象和顏色。 要檢測 APK 中可能被刪除的未使用資源,請使用 android-unused-resources 工具。 Android Unused Resources 是一個 Java 應用程序,它將掃描您的項目以查找未使用的資源。
6) 避免重複確保您的應用程序沒有重複的功能或重複的資產是避免在 APK 中包含不必要文件的明顯方法。 了解您使用哪些 Android API 以及每個 API 提供的完整功能非常重要。 可能是一個 Android API 已經在做另一個 API 的工作。 重複的資產(字符串、位圖等)也很浪費空間,而且很容易避免。 在較小程度上,重複的代碼也會不必要地增加交付的二進製文件的大小。
7) 減少方法數量Avid Android 開發人員一直面臨著他們的應用程序中令人頭疼的問題。 應用程序可以擁有的方法數量是有限的。 好吧,它曾經是有限的。 終於,去年 10 月,Google 的好人提供了解決方案,但遠非理想。 雖然非常容易實現,但 multidex 解決方案複雜且顯著延長了編譯時間。 沒有停滯不前,從 Lollipop (Android 5.0) 開始,整個 Android 虛擬機發生了革命性的變化,以提供更持久的解決方案,這種解決方案甚至改進了常規編譯時間。 然而,就目前而言,Lollipop 解決方案也並不理想。 它要求開發人員僅針對 Lollipop 進行開發,這可能會出現問題,因為大多數應用程序都希望與更廣泛的受眾兼容,並且可能會擔心使用早期 Android 版本中不可用的功能。 所以現在,Lollipop 解決方案是一個很好的未來——Android 解決方案,但在可預見的現在可能不會產生太大影響。 那麼在此期間可以做些什麼呢? 我們都同意你不應該放棄特性和功能,只是為了避免達到 65K 的限制。 但毫無疑問,最佳實踐仍然是減少您的應用程序方法數。 那麼,如何在不丟失使您的應用與眾不同的小火花的情況下仍然嘗試減少方法數呢?
簡短概述:“所有這些方法都來自哪裡?”
方法計數限制大致為 65K 方法(準確地說是 65,536)。 這聽起來是一個巨大的數字。 如果您是一名新手 Android 開發人員,您可能會想“這麼多應用程序怎麼能這麼快達到這個數字?” 你可能有點正確。 自己寫這麼多方法並不容易。 但是應用程序開發人員不會自己編寫整個應用程序。 應用程序開發人員正在使用越來越多的第三方庫(SDK - 軟件開發工具包),這有助於他們實現某些目標和功能,否則他們必須完全自行開發。 從廣告到 GUI 增強,再到社交網絡、崩潰報告等等,SDK 提供了廣泛的功能和 API,可以節省寶貴的開發時間並幫助您更快地推出應用程序。 但是每個 SDK 都會增加您的方法數量,並且一些 SDK 的功能甚至超出了您的預期。 當然,這不一定是壞事。 然而,致命一擊來自谷歌自己。 他們的 Google Play 服務套件是一個包含 28,000 多個方法的大型 SDK。 限制為 65K,這個數字並不低。 許多應用程序開發人員都喜歡使用這個 SDK,因為它打開了通往神奇的 Google 王國的大門,這是一個非常需要的功能,可以為應用程序增加大量價值。 在這篇文章中,我不僅會解釋如何有選擇地使用 Google Play 服務包,還會告訴你這些包中的每一個都為你的應用程序添加了多少方法。 所以請穩住自己的座位,這將是一段顛簸的旅程。
Google Play 服務遊樂場
那麼 Google Play Services 實際添加了多少方法呢? 好吧,就像生活中的一切一樣,它比一個底線數字要復雜得多。 但是,讓我們一步一步來。 Google Play 服務 SDK 實際上包含 19 個不同的 SDK。 使用 Gradle,您可以有選擇地選擇使用哪些。 您所要做的就是將以下依賴項添加到您的應用程序模塊的build.gradle文件中:
依賴{ 編譯'com.google.android.gms:play-services:7.5.0' }
7.5.0 是此時發布的最新 GPS 版本。 它在 Android SDK 管理器中標記為修訂版 25。 為了選擇特定的包,用你想要的任意多的依賴行替換下面的行,指定特定的包。 例如,您只想要 Google Plus、Google Games、Google Ads 和 Google Maps:
依賴{ 編譯'com.google.android.gms:play-services-plus:7.5.0' 編譯'com.google.android.gms:play-services-games:7.5.0' 編譯'com.google.android.gms:play-services-ads:7.5.0' 編譯'com.google.android.gms:play-services-maps:7.5.0' }
不太難,但這是第一個問題。 光榮的 19 個 SDK 之一稱為 play-services-base。 如果您包含任何 Google Play 服務包,它也會自動添加。 基礎包包含多少個方法? 將近 8,000 個(具體數字如下)。
這是第二個問題。 在上面的示例中,我沒有隻包含 3 個包。 如果你也算上基本包,我什至不只包括 4 個。 事實上,我包括了 5 個包。 為什麼? 因為 Google Games 包使用了 Google Drive 包,所以它也被導入了(實際上,Google Ads 還包括一個名為標籤管理器的包,但我這裡只計算“可選”包)。
所以現在我們開始理解為什麼要計算每個 Google Play 服務包向我們的應用程序添加了多少方法有點困難。 包括一個包,並不一定意味著排除其他包。
所以這裡是最底層的——你可以添加哪些包,他們添加了多少方法,以及他們帶來了哪些其他包來破壞派對。 數據指的是最新版本的 Google Play 服務(7.5.0 / 修訂版 25):
方法總數:28,175。您必須承認,其中一些數字確實很殘暴。 如果你想要的只是全景包,你不能只得到九種方法,你必須得到近8000個。 難怪有如此多的應用程序接近或超過 65K 的限制。
如果您嘗試將其中一些數字相加,它們中的一些似乎有點不一致。 那是因為,Google Play 服務背後的邏輯比看上去要復雜一些。 例如,Google Analytics 包含來自 Google Ads 的單一方法,以獲取帳戶的廣告 ID。
請注意,在計算每個包添加到您的應用程序中的數量時,請務必排除雙精度包(例如,不要多次計算基本包)。
您不能有選擇地添加所有內容
這是最後的刺痛。 Google Play Services 中有兩個無法選擇性添加的小包。 搜索包(允許您訪問 Google Now API)僅包含 22 種方法。 如果你想使用它,你別無選擇,只能添加整個 28,000 多個方法,整個 Google Play 服務。 希望這將在以後的版本中得到修復。
(另一個“無法訪問”的包是包含 111 個方法的appstate包,但是現在不推薦使用它,取而代之的是SavedGames ,包含在 google-play-games 包中)。