編輯:關於Android編程
Android的apk文件越來越大了這已經是一個不爭的事實。在Android 還是最初版本的時候,一個app的apk文件大小也還只有2 MB左右,到了現在,一個app的apk文件大小已經升級到10MB到20MB這個范圍了。apk文件大小的爆炸式增長主要是因為用戶對app質量的期待越來越高以及開發者的開發經驗增長,具體體現在以下幾個方面:
Android開發者在設計一個app的時候應該將最終發布一個輕量級app作為一個最佳實踐來考慮。為什麼?首先這就意味著你擁有了一個簡潔,易維護代碼基礎。其次,官方應用商店對超過50MB的apk設置了拓展包文件下載選項,apk文件在50MB以下更容易讓用戶下載。最後,我們的應用程序環境是一個帶寬有限,存儲空間有限的環境,apk安裝文件越小,下載就會越快,安裝也會更快,良性循環,最後說不定用戶因為這個給好評。
在大部分情況下,apk大小的增長是為了滿足消費者的需要和期待。然而,我認為apk大小的增速已經超過了用戶對app期待的增速。所以,很大程度上,官方應用商店裡面的那些程序可以瘦身至它們現在大小的一半甚至更多。在這篇文章裡面,我將寫下一些關於如何給apk文件瘦身的招式,希望你們能夠喜歡。
在說如何給apk瘦身之前,讓我們先來看看apk文件內部的結構到底是怎麼一回事。說簡單點,一個apk文件就是包含一些文件的壓縮包。作為開發者,我們通過使用 unzip
命令解壓這個apk文件一探apk的內部結構。下面的文件結構就是我們使用 unzip
1這個命令所獲得的:
我們可能對上面大部分的文件和目錄都很熟悉。它們和我們在實際開發app的時候所看到得項目結構一樣,包含了: /assets
, /lib
, /res
, AndroidManifest.xml
. 還有一些文件可能是我們第一次看到。一般說來,classes.dex
, 它包含了我們所寫的Java代碼經過編譯後class文件;resources.arsc
包含了預編譯之後的資源文件(比如values文件,XML drawables 文件等。)。
由於apk文件只是一個簡單地壓縮文件,這就意味著它有兩種大小:即壓縮前的大小和壓縮後的大小。這篇文章我將主要關注壓縮後的大小。
減少apk文件大小可以從幾個方面入手。由於每個app都是不同的,所以沒有什麼絕對規則來給apk文件瘦身。作為apk文件的三個重要組成部分,我們可以考慮從它們開始入手:
所以接下來的招式都是由減少這些組件的大小出發,進而減少整個app的大小。
這是減少apk文件至關重要的第一步。你要對自己的代碼了如子掌。你要移除掉所有無用處的dependency libraries,讓你的代碼一天比一天優秀,持續地優化你的代碼。總而言之,保持一個簡潔,最新的代碼基礎是減少apk文件至關重要的一環。
當然,從零開始一個項目並為這個項目保持一份簡潔的代碼基礎很容易。項目越老,這個工作就越困難。事實上,擁有一大段歷史背景的項目必須要去處理各種死代碼和無用代碼。還好有許多的開發工具可以幫我們來做這些事情……
Proguard 是一個很強悍的工具,它可以幫你在代碼編譯時對代碼進行混淆,優化和壓縮。它有一個專門用來減少apk文件大小的功能叫做 tree-shaking。Proguard 會遍歷你的所有代碼然後找出無用處的代碼。所有這些不可達(或者不需要)的代碼都會在生成最終的apk文件之前被清除掉。Proguard 也會重命名你的類屬性,類和接口,然整個代碼盡可能地保持輕量級水平。
也許現在你會認為 Proguard 是一個相當有效地工具。但是能力越大,責任也就越大。現在許多開發這認為Proguard有點讓人不省心,因為它會重度依賴反射。哪些類或者屬性需要被處理或者不能處理都要開發者對 Proguard 進行配置。
Proguard 只會對 Java 代碼起作用,那麼對哪些資源文件呢?比如一張圖片 my_image
在 res/drawable
文件夾中,沒有被使用,Proguard 只會移除掉 R
類中的引用,但是圖片依然還在文件夾中。
Lint 一個靜態的代碼分析器,你只需通過調用 ./gradlew lint
這個簡單地命令它就能幫你檢查所有無用的資源文件。它在檢測完之後會提供一份詳細的資源文件清單,並將無用的資源列在“UnusedResources: Unused resources” 區域之下。只要你不通過反射來反問這些無用資源,你就可以放心地移除這些文件了。
Lint 會分析資源文件(比如 /res
文件夾下面的文件) ,但是會跳過 assets 文件 ( /assets
文件夾下面的文件)。事實上assets 文件是可以通過它們的文件名直接訪問的,而不需要通過Java引用或者XML引用。因此,Lint 也不能判定某個 asset 文件在項目中是否有用。這全取決於開發者對這個文件夾的維護了。如果你沒有使用某個asset 文件,那麼你就可以直接清除這個文件。
Android 支持多種設備。Android的系統設計讓它可以支持設備的多樣性:屏幕密度,屏幕形狀,屏幕大小等等。到了Android 4.4,它支持的屏幕密度包括: ldpi, mdpi, tvdpi, hdpi, xhdpi, xxhdpi and xxxhdpi。但是你要知道的一點是,Android 支持這麼多的屏幕密度並不意味著你需要為每一個屏幕密度提供相應的資源文件。
如果你知道某些屏幕密度的設備只有很少部分用戶在使用,那麼你就可以直接不需要使用相應屏幕密度的資源文件。就我個人而言,我只會為我的應用提供 hdpi, xhdpi and xxhdpi2 這幾個屏幕密度的支持。如果某些設備不是這幾個屏幕密度的,不用擔心,Android 系統會自動使用存在的資源為設備計算然後提供資源文件。
我這麼做得原因很簡單。首先,這些設備屏幕密度就能覆蓋我 80% 的用戶。其次,xxxhdpi 這個屏幕密度只是在為未來的設備做准備,但是未來還未到來。最後,我真的不怎麼關心低屏幕密度(比如mdpi 和 ldpi),無論我為這幾個屏幕密度努力,結果都是令人傷心地,還不如直接讓Android系統對 hdpi 資源文件進行適當地縮放來匹配相應地低端機型。
同樣地,在 drawable-nodpi
文件夾裡面維持一個文件也能節省空間。當然前提是你覺得對這個文件進行相應地縮放之後呈現的效果你能接受或者這個文件出現的幾率很少。
Android 開發經常會依賴各種外部開源代碼庫,比如Android Support Library, Google Play Services, Facebook SDK 等等。但是這些庫裡面並不是所有的資源文件你都會用到。比如, Google Play Services 裡面會有一些為其他語種提供翻譯,而你的app又不需要這個語種的翻譯,而且這個庫裡面還包含了我的app中不支持的 mdpi 資源文件
還好從Android Gradle Plugin 0.7 開始,你可以配置你的app的build系統。這主要是通過配置resConfig
和 resConfigs
以及默認的配置選項。下面的 DSL (Domain Specific Language)就會阻止 aapt(Android Asset Packaging Tool)打包app中不需要的資源文件。
之前博主講xUtils的時候,介紹過注解,不過是蜻蜓點水,有興趣的同學可以先移步到xUtils介紹2,今天我們就來詳細解剖一下Android中注解的使用。 Java注解是
在上一篇雷達圖中留下了一個坑——折線圖。折線圖(broken-line graph)大概是初中數學就開始學習的,用來統計一段時間內某個數據的趨勢。
Android 深入解析selector selector類同於shape都是xml文件設置控件的屬性,然後再進行引用。 selector 基本屬性如下:
前言:前面幾篇總結一些TV上的小Sample,開源到GitHub:https://github.com/hejunlin2013/TVSample, 點擊鏈接,可以持續關