SmallerAPK,第1部分:APK的剖析
如果我問一堆開發人員他們的應用程式的大小是什麼,我很確定大多數人會檢視Android Studio生成的APK檔案並告訴我他們的計算機佔用了多少磁碟空間。這是最直接的答案,它在技術上是正確的,但也許我應該問更好的問題。考慮這些例如:
- 安裝在使用者裝置上時,您的應用佔用了多少空間?
- 使用者下載和安裝應用程式需要支付多少網路資料?
- 現有使用者的應用更新下載大小有多大?
- 執行應用程式的記憶體佔用量(就使用的RAM而言)是多少?
如果您是一名擁有高階手機的開發人員,您可能想知道是否值得花時間優化APK大小...請記住,並非所有裝置都具有相同的儲存,記憶體或網路連線。
世界上有些地方使用者必須為他們下載的每兆位元組資料付費,而且每個角落都沒有Wi-Fi熱點。
有些裝置沒有內部儲存容量(磁碟空間)來讓使用者安裝他們需要的所有應用程式,這意味著他們必須在安裝或更新任何軟體之前三思而後行。誰知道,這些可能是你的下一個千萬或幾百萬使用者,所以讓我們試著讓那個APK更小!它將使每個人受益。
當然,考慮到我們都必須處理的各種要求和約束,很難選擇一刀切的解決方案。有時,犧牲初始下載大小將加速後續更新。在其他情況下,與直覺相反,在APK中保持檔案未壓縮可以減少裝置上的最終磁碟空間量。我將嘗試突出這些權衡並在適用的地方提供解釋,但最終由您(開發人員)選擇對您的應用和使用者有意義的混合技術。
執行時記憶體佔用空間大多超出了本系列文章的範圍。所呈現的優化可能對記憶體使用和效能產生一些小的副作用,包括正面和負面。我會嘗試在適用的時候提及任何明顯的缺點,但是由讀者來衡量你的應用程式的效能特徵並進行最後的呼叫。記住,#permatmatters!
什麼是APK
在我開始討論如何縮小應用程式之前,讓我們首先看一下檔案格式本身。APK實際上只是一個ZIP存檔,包含構成應用程式的檔案。通常在APK中,您會找到以下條目:
classes.dex
包含已編譯的應用程式程式碼,轉換為Dex位元組碼。如果您使用multidex來克服65536方法限制,您可能會在APK中看到多個DEX檔案。從介紹ART執行時的Android 5.0開始,這些在安裝時由提前編譯器編譯成OAT檔案並放在裝置的資料分割槽上。您可以在第2部分:縮小程式碼中學習如何減小dex程式碼的大小
RES /
此資料夾包含大多數XML資源(例如佈局)和drawables(例如PNG,JPEG)在具有各種限定符的資料夾中,例如-mdpi和-hdpi用於密度,-sw600dp或-large用於螢幕大小和-en,-de,-pl對於語言。請注意,res /中的任何XML檔案在編譯時都已轉換為更緊湊的二進位制表示,因此您無法使用APK內部的文字編輯器開啟它們。
第3部分:刪除未使用的資源顯示瞭如何通過在專案中使用陳舊資源來確保不浪費空間。在第4部分:多APK,ABI和密度分割以及第5部分:通過產品風格的多APK中,我們討論如何根據硬體特徵在多個APK上劃分資產,這些APK針對特定裝置組。第6部分:影象優化,Zopfli和WebP以及第7部分:影象優化,Shape和VectorDrawables處理各種優化技術,使影象更小。
resources.arsc
一些資源和識別符號被編譯並展平到此檔案中。它通常儲存在APK中而不進行壓縮,以便在執行時更快地訪問。手動壓縮此檔案似乎很容易獲勝,但實際上至少有兩個原因並不是一個好主意。一,Play Store壓縮任何資料以進行傳輸和兩個,在APK內壓縮檔案會浪費系統資源(RAM)和效能(尤其是app啟動時間)。
第3部分將展示兩種方法,通過僅包含對您的應用有意義的語言的字串,使該檔案更加精簡。
AndroidManifest.xml中
與其他XML資源類似,您的應用程式清單在編譯期間轉換為二進位制格式。Play商店使用AndroidManifest中包含的某些資訊來決定是否可以在裝置上安裝APK,檢查允許的密度或螢幕大小以及可用的硬體和功能(例如觸控式螢幕)。如果要在編譯後檢查這些Manifest條目,可以使用Android SDK中的aapt工具:
$ aapt dump badging your_app.apk
庫/
任何本機庫(* .so檔案)都將放在以libs /資料夾為目標的ABI(CPU架構,例如x86,x86_64,armeabi-v7a)命名的子資料夾中。通常,它們會在安裝時從APK複製到您的/ data分割槽。但是,由於APK本身在使用者裝置上不會被更改,因此這實際上會使任何本機庫所需的空間翻倍。本文的第8部分(本機庫,從APK開啟)為Android 6.0+上的此問題提供瞭解決方案,還可以在舊裝置上節省網路頻寬。
資產/
此資料夾用於任何不會用作Android型別資源的檔案資產。最常見的是字型檔案或遊戲資料,如關卡和紋理,以及您希望直接作為檔案流開啟的任何其他應用程式資料。
META-INF /
此資料夾存在於已簽名的APK中,幷包含APK及其簽名中所有檔案的列表。目前在Android中籤名的方式是,它逐個驗證來自存檔的未壓縮檔案內容的簽名。
這有一些有趣的後果。由於ZIP檔案中的每個條目都是單獨儲存的,這意味著您可以更改單個檔案的壓縮級別而無需重新簽名。但是,如果您在簽名後從歸檔中刪除任何檔案,則簽名驗證將失敗。
關於如何建立已簽名的APK的另一個注意事項是zipalign工具用作構建的最後一個階段。如果您手動更改存檔的內容,通常您需要重新簽名,然後在將APK上傳到Play商店之前進行zipalign。
使用Zopfli重新壓縮APK(不要這樣做)
更新:此前本文包含一個部分,使用更強大的壓縮演算法Zopfli重新壓縮APK中的檔案。此功能現在已從Android Studio 2.2中的構建工具中刪除,不再推薦使用,因為它可能會影響將Play Store增量更新更小的未來計劃。
如果您仍然不相信停止使用Zopfli作為您的APK,讀者已經提醒我,某些Android 5.0.1裝置可能在閱讀Zopfli壓縮的APK時遇到問題,甚至可能導致您的應用崩潰。
無論如何,本指南的下一章應該是您的主要關注點,並且比使用Zopfli為APK提供多10倍的節省。
+qq群457848807:。獲取以上高清技術思維圖,以及相關技術的免費視訊學習資料
相關文章
- Spring 的優秀工具類盤點第 1 部分Spring
- 《Divinuet》的互動音樂系統 – 第 1 部分
- mORMot模糊概念--FormatSQL-第1部分ORMSQL
- 【譯】什麼是SOLID原則(第1部分)Solid
- [譯] Xcode 和 LLDB 高階除錯教程:第 1 部分XCodeLLDB高階除錯
- Django入門指南-第1部分(環境搭建)Django
- 遊戲音訊存檔 | 第 1 部分:基本情況遊戲音訊
- Java XML和JSON:Java SE的文件處理,第1部分JavaXMLJSON
- [Flutter翻譯]Flutter Anatomy - 佈局內部的第1部分Flutter
- [How HTTPS works Part 1 — Building Blocks] HTTPS 的工作方式第 1 部分-基本構造塊HTTPUIBloC
- 如何構建一個多人(.io) Web 遊戲,第 1 部分Web遊戲
- [譯]使用 Rust 開發一個簡單的 Web 應用,第 1 部分RustWeb
- Webpack 系列第 3 部分Web
- Vue文件中幾個易忽視部分的剖析Vue
- 資深專家深度剖析Kubernetes API Server第1章(共3章)APIServer
- 使用Go構建區塊鏈 第1部分:基本原型Go區塊鏈原型
- 在Go中構建區塊鏈 第4部分:交易1Go區塊鏈
- 在 Flutter 中編寫自定義小部件(第1部分)ー EllipsizedTextFlutterZed
- Cocos Creator 資源載入流程剖析【三】——Load部分
- 理解音訊焦點 (第1/3部分):常見的音訊焦點用例音訊
- 《Divinuet》的互動音樂系統 – 第 2 部分
- 【Android APK】解析SD卡上的APK檔案AndroidAPKSD卡
- SpringCloud第而部分以及SpringCloudAlibaba筆記SpringGCCloud筆記
- mmdetection原始碼剖析(1)--NMS原始碼
- Cordova 打包 apk,html 打包 apkAPKHTML
- Flutter的apk打包FlutterAPK
- Linux DNS 查詢剖析(第三部分)LinuxDNS
- 第1章 DevOps的理想dev
- 遊戲和影視行業在音訊製作上的一些區別 – 第 1 部分遊戲行業音訊
- [譯] Node.js 高效能和可擴充套件應用程式的最佳實踐 [第 1/3 部分]Node.js套件
- 第 15 期 多路複用資源池元件剖析元件
- 河南萌新聯賽2024第(三)場(部分)
- 10 個 Flutter 建議 ー 第 8/10 部分Flutter
- 第1章 引言
- ARTS:第 1 期
- [譯] Transducers: JavaScript 中高效的資料處理 Pipeline(第 18 部分)JavaScript
- 第1節:GTID的基本概念
- Apk 簽名的那些事APK