Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android Develop:減小APK大小

Android Develop:減小APK大小

編輯:關於Android編程

用戶通常會避免下載過大的app,尤其是在新興市場,那裡的設備網絡連接2G和3G往往參差不齊,或者以按流量收費的形式。這篇文檔描述了如何減少你的app的APK大小,它會使得更多的用戶下載你的app;


理解APK的結構
--------------------------------------------------------------------------------

在討論如何減少你的app的大小之前,理解一個app的apk結構是非常有用的。一個APK文件是一個zip壓縮文件,它包含你的app的所有文件。這些文件包含Java類文件,資源文件,和一個編譯資源的文件。

一個APK包含下面的目錄:

  • META-INF/:包含CERT.SF和CERT.RSA簽名文件,和MANIFEST.MF清單文件;

  • assets/:包含app的assets,app可以使用一個AssetManager對象獲取它;

  • res/:包含沒有編譯到resources.arsc中的資源;

  • lib/:包含為特定處理器編譯的代碼。這個目錄包含不同平台類型的子目錄,如armeabi,armeabi-v7a,arm64-v8a,x86,x86_64和mips;

一個APK也包含下面的文件。在它們裡面,只有AndroidManifest.xml是必須的。

  • resources.arsc:包含被編譯的資源。這個文件包含來自res/values目錄下所有配置的XML內容。打包工具提取XML內容,將它們編譯為二進制的形式,並且打包。這些內容包含語言字符串和樣式,和在resources.arsc文件不包含的內容的路徑,如布局文件和圖片;

  • Classes.dex:包含被編譯的類,以Dalvik/ART虛擬機能理解的dex文件格式;

  • AndroidManifest.xml:包含核心的Android清單文件。這個文件羅列了名稱,版本,訪問權限,和app引用的庫文件。這個文件使用Android的二進制XML格式;


減少資源數目和大小
--------------------------------------------------------------------------------

你的apk的大小對你的app的加載速度,使用內存大小和消耗功率多少有一定影響。使你的apk變小的一種簡單方式就是減少它包含資源的數目和大小。尤其是,你要移除你的app不再使用的資源,並且你可以使用Drawable對象代替圖片文件。這個章節討論了這些,和其它一些能減少你的app資源的方法,來減少你的APK的整體大小。

移除不使用的資源

在Android Studio中的一個靜態代碼工具lint,檢測在你的/res目錄下代碼沒有引用的資源。當lint工具在你的項目中發現一個潛在的未使用的資源,它會打印一條如下示例的消息。

res/layout/preferences.xml: Warning: The resource R.layout.preferences appears
to be unused [UnusedResources]

注意:lint工具沒有掃描assets/目錄,assets通過反射引用,或者你的app鏈接的庫文件。另外,它不會移除資源;它僅僅是提醒你它們的存在;

你添加到你的代碼中的庫可能包含未使用的資源。如果你在你的app的build.gradle文件中啟動shrinkResourcesGradle,它能自動替你刪除這些資源。

android{
// Other settings

buildTypes{
release{
minifyEnabledtrue
shrinkResourcestrue
proguardFiles getDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro'
}
}
}

為了使用shrinkResources,你必須啟動代碼壓縮。在構建的過程中,首先ProGuard移除了沒有使用的代碼,但是還存在沒有使用的資源。然後Gradle會移除沒有使用的資源。

更多關於ProGuard的信息,和其它Android Studios幫助你減少APK大小的方式,查閱Shrink Your Code and Resources。

在Android Gradle插件0.7或者更高版本,你可以聲明你的app支持該配置。Gradle通過使用resConfig和resConfigs flavor和defaultConfig向構建系統傳遞信息。構建系統然後禁止在APK中出現其它來源的資源,不支持的配置,減小APK的大小。更多的關於這個功能的信息,請查閱Remove unused alternative resources。


減少庫中使用的資源

在開發Android app的時候,你通常會使用擴展庫來提升你的app的可用性和多功能性。例如,你可能引用Android Support Library來提升在老設備上的用戶體驗,或者你可能使用Google Play Services來檢索自動翻譯你的app中的文本。

如果一個庫針對server和desktop設計,它會包含許多你的app不需要的對象和方法。為了僅僅包含你的app需要的庫的這部分,如果允許你修改這個庫,你可以編輯這個庫的文件。你也可以使用一個可選的,針對移動端設計的庫來為你的app添加具體的功能。

注意:ProGuard能清除導入的庫不必要的代碼,但是它不能移除庫龐大的內部依賴。


只支持特定的密度

Android支持一個非常大的設備集合,包括各種屏幕密度。在Android4.4(API Level 19)和更高版本,framework支持各種各樣的密度:ldpi,mdpi,tvdpi,xhdpi,xxhdpi和xxxdpi。盡管Android支持所有這些密度,你不需要為每個密度制作資源。

如果你知道你的用戶只有一小部分使用特定密度,考慮下你是否需要將這些密度捆綁你的app中。如果你不包含某一指定屏幕密度的資源,Android自動縮放存在的,原來為其它屏幕密度設計的資源。

如果你的app僅僅需要被縮放的圖片,你可以通過在drawable-nodpi/目錄中保存圖片的一個變體,來節省更多的空間。我們要求任何app至少包含一個xxxhdpi圖片變體;

更多關於屏幕密度的信息,請查閱Screen Sizes and Densities。


減少動畫幀

幀動畫可以徹底減少你的APK的大小。下圖展示了一個幀動畫被分離成多張圖片保存在目錄中的例子。每個圖片在動畫中是為一幀。

對於你添加到動畫中的每一幀,你增加了在APK中圖片的數量。如下圖,在app中這個圖片動畫30幀。如果圖片動畫用僅僅15幀代替,這個動畫僅僅需要一半數量的幀。

 
  • aapt工具不會壓縮在asset/目錄下的PNG文件;

  • aapt工具只優化使用256或者更少的顏色的圖片文件;

  • aapt工具可能會增加已經被壓縮過的PNG圖片。為了防止這個,你可以在Gradle中使用cruncherEnabled標識來取消PNG圖片的優化過程;
aaptOptions{
cruncherEnabled=false
}


壓縮PNG和JPEG文件

你可以使用如pngcrush,pngquant或者aopflipng來減小PNG文件的大小,並且不降低圖片的質量。所有的這些工具都可以減少圖片的大小並且保持圖片的質量。

pngcrush工具尤其有效:這個工具迭代PNG過濾器和zlib參數,使用每個過濾器組合和參數來壓縮圖片。然後選擇最小壓縮配置輸出。

對於JPEG文件,你可以使用如packJPG工具來將JPEG文件壓縮為更緊湊格式。


使用webp文件格式

你可以使用WebP文件格式,代替使用PNG或者JPEG文件。Webp格式支持有損壓縮(像JPEG)和透明度(如PNG),但比JPEG或PNG的壓縮更好。

使用WebP文件格式有幾個顯著的缺點。首先,在低於Android3.2系統版本(API level 13)不支持Webp格式。其次,系統解碼WebP相比PNG圖片會消耗了更多的時間。

注意:Google Play僅僅接受使用PNG格式圖標的APK。如果你想通過Google Play發布你的app的話,你不能使用其它文件格式如JPEG或者WebP用戶app的圖標。


使用矢量圖

你可以使用矢量圖來創建獨立於分辨率的圖標和其它可擴展的媒體。使用這些圖標可以大大減少你的apk。矢量圖在Android中以VectorDrawable對象代表。使用VectorDrawable對象,一個100-byte文件可以生成一個屏幕大小清晰圖像。

然而,每個VectorDrawable對象的渲染明顯的消耗了系統時間,並且更大的圖片需要更長的時間來展示在屏幕上。因此僅僅在顯示小的圖片的時候考慮使用矢量圖。

更新關於使用VectorDrawable對象的信息,請查閱Working With Drawables。


減少Native和Java代碼
--------------------------------------------------------------------------------

這裡有幾種你可以用來減少app的Java和native代碼大小的方式。


刪除不必要生成的代碼

一定要明白任何自動生成代碼的足跡。例如,許多協議緩沖工具生成過多的方法和類,它會兩三倍的增加你的app的大小。


移除枚舉

一個枚舉會增加你的app的class.dex文件大約1.0到1.4K的大小。對於復雜的系統或者共享庫這種情況會更加明顯。如果可能的話,考慮使用@IntDef和ProGuard來剝離枚舉,並轉換成Integer。這種類型轉換保留了所有枚舉的安全效益。


減少Native庫的大小

如果你的app使用了native代碼和Android NDK,你也可以通過優化你的代碼減少你的app的大小。兩個有用的技術是移除Debug符號和避免取native庫。

移除Debug符號

使用debug符號意味著著你的應用程序正在開發並且持續需要debug。使用在Android NDK中提供的arm-dabi-strip工具,來移除不必要的native庫的debug符號。在這之後,你可以編譯你的release構建。

避免提取Native庫

保存APK中解壓的.so文件,並且設置在你的應用清單文件中元素中的android:extractNativeLibs標識為false。這將會阻止PackageManager在安裝的過程中從APK中復制出.so文件到文件系統中,並且將增加使得你的app的增量更新更小的好處。

維護多個精簡的APK

--------------------------------------------------------------------------------

你的apk包含了用戶下載但是從來不使用的內容,例如區域的或者語言信息。為了給你的用戶提供一個最小的下載,你可以以屏幕尺寸或者GPU類型劃分,將你的app分給為多個APK。

當一個用戶下載你的應用的時候,他們的設備根據設備的功能和配置獲取對應的APK。這種方式下,設備不會獲取它沒有功能的資源。例如,如果一個用戶有一個hdpi的設備,他們不需要xxxhdpi資源,你可能為了更高的密度設備顯示而包含。

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved