安裝包的性能優化的精髓:盡量刪。
安裝包的性能優化方法:
1.圖片壓縮
圖片:apk里面的資源圖片 壓縮圖片
svg圖片:一些圖片的描述,犧牲CPU的計算能力的,節省空間。
使用的原則:簡單的圖標。webp:谷歌現在非常提倡的使用。保存圖片比較小。
VP8派生而來的。webp的無損壓縮比PNG文件小45%左右,即使PNG進過其他的壓縮工具壓縮后,
任然可以減小到PNG的28%。Facebook在用、騰訊、淘寶。
缺點:加載相比于PNG要慢很多。 但是配置比較高。
圖片壓縮工具:tinypng.com/
圖片壓縮轉換工具:isparta.github.io/
2.資源動態加載
比如:emoji表情、換膚、動態下載的資源、一些模塊的插件化動態添加
3.使用AS自帶的Lint工具刪除無用資源
1)檢測沒有用的布局 刪除
2)未使用到的資源 比如 圖片 ---刪除
3)建議String.xml有一些沒有用到的字符。
4.極限壓縮
7zZip工具的使用。
5. lib資源優化
(1)動態下載的資源。
(2)一些模塊的插件化動態添加。
(3)so文件的剪裁和壓縮。
6. assets資源優化
(1)音頻文件最好使用有損壓縮的格式,比如采用opus、mp3等格式,但是最好不要使用無損壓縮的音樂格式
(2)對ttf字體文件壓縮,可以采用FontCreator工具只提取出你需要的文字。比如在做日期顯示時,其實只需要數字字體,但是使用原有的字體庫可能需要10MB大小,如果只是把你需要的字體提取出來生成的字體文件只有10KB。
7.Proguard 混淆
7.1 概念
資源混淆簡單來說希望實現將res/drawable/icon,png變成res/drawable/a.png,或我們甚至可以將文件路徑也同時混淆,改成r/s/a.png。
注意:此時的混淆在AS自帶的混淆做完后再壓縮混淆。AS自帶的混淆是做代碼內容的混淆,我們這個混淆是文件名。
7.2 apk編譯原理
7.2.1 編譯原理圖
Android應用程序主要由兩部分內容組成:代碼和資源。資源主要就是指那些與UI相關的東西,例如UI布局、字符串和圖片等。代碼和資源分開可以使得應用程序在運行時根據實際需要來組織UI。這樣就可使得應用程序只需要編譯一次,就可以支持不同的UI布局。這種特性使得應用程序在運行時可以適應不同的屏幕大小和密度,以及不同的國家和語言等。
7.2.1 aapt編譯
aapt即Android Asset Packaging Tool,在SDK的build-tools目錄下。該工具可以查看,創建, 更新ZIP格式的文檔附件(zip, jar, apk)。也可將資源文件編譯成二進制文件。
通過圖我們就可以看出:
A. 除了assets和res/raw資源被原裝不動地打包進APK之外,其它的資源都會被編譯或者處理。
B. 除了assets資源之外,其它的資源都會被賦予一個資源ID。
C. 打包工具負責編譯和打包資源,編譯完成之后,會生成一個resources.arsc文件和一個R.java,前者保存的是一個資源索引表,后者定義了各個資源ID常量。
D. 應用程序配置文件AndroidManifest.xml同樣會被編譯成二進制的XML文件,然后再打包到APK里面去。
E. 應用程序在運行時通過AssetManager來訪問資源,或通過資源ID來訪問,或通過文件名來訪問。
其中resources.arsc文件,這個文件記錄了所有的應用程序資源目錄的信息,包括每一個資源名稱、類型、值、ID以及所配置的維度信息。我們可以將這個resources.arsc文件想象成是一個資源索引表,這個資源索引表在給定資源ID和設備配置信息的情況下,能夠在應用程序的資源目錄中快速地找到最匹配的資源。
7.2.3 resources.arsc文件解析
(1)Resource.arsc文件格式圖
resources.arsc一共有五種chunk類型,分別為TYPETABLE,TYPEPACKAGE,TYPE_STRING ,TYPETYPE,TYPECONFIG。
—table,是整個reousces table的開始,它的chunksize即是整個文件的大小。
—package,指的是一個package的開始,其實在resources,arsc是可以有多個package的。而packageID即是資源resID的最高八位,一般來說系統android的是1(0x01),普通的例如com.tencent.mm會是127(0x7f),剩下的是從2開始起步。當然這個我們在aapt也是可以指定的(1-127即八位的合法空間,一些混合編譯就是改這個packageID)。
—string, 代表stringblock,我們一共有三種類型的stringblock。分別是table stringblock,typename stringblock, specsname stringblock。
—type,這里講的是typename stringblock里面我們用到的各種type(用到多少種類型的type,就有多少個type chunk),例如attr, drawable, layout, id, color, anim等,Type ID是緊跟著Package ID。
—config, 即是Android用來描述資源維度,例如橫豎屏,屏幕密度,語言等。對于每一種type,它定義了多少種config,它后面就緊跟著多少個config chunk,例如我們定義了drawable-mdpi,drawable-hdpi,那后面就會有兩個config。
將Resource.arsc文件部分內容讀出顯示如下:
7.3 混淆過程
系統編譯完成apk文件以后:
映射關系:res/drawable/ic_launcher.png —– > 0x7f020000
再做“混淆”:要實現將res/drawable/ic_launcher.png圖片改成a.png
drawable文件的名字
String文件的名字
layout的名字
比如:R.string.description—>R.string.a
res/drawable/ic_launcher.png圖片改成a.png
還可以更加夸張
res/drawable—>r/d
res/value–>r/v
res/drawable/ic_launcher.png圖片改成r/d/a.png
讀取resources.arsc二進制文件,然后修改某一段一段的字節。
有一段叫做:res/drawable/ic_launcher.png 在自己數組當中的第800位-810位
將這一段第800位-810位替換成改成r/d/a.png 的字節碼。
8.zipalign優化
我們知道APK其實就是一個Zip壓縮文件,從原理上來講就是通過格式化Zip文件夾中二進制文件的序列,達到提升系統解析速度。就像我們在閱讀代碼的過程中先格式化一遍代碼,會讓我們更容易理解其含義一樣。在Android平臺中,數據文件存儲在apk文件中,可以多進程的訪問,如果你開發過Win32可能知道程序的粒度對齊問題,不錯雖然不是PE格式的文件,在Zip中一樣,資源的訪問可以通過更好的對其優化,而zipalign使用了4字節的邊界對齊方式來影射內存,通過空間換時間的方式提高執行效率。
我理解的是:通俗的說就是按著有利于系統處理的排列方式,對我們apk中的資源文件進行排列,提高資源的查找速度,從而去提高應用的運行效率。
先簽名再對齊,否則先對齊再簽名會破壞對齊
使用
release {
// 不顯示Log
buildConfigField "boolean", "LOG_DEBUG", "false"
//混淆
minifyEnabled true
//Zipalign優化
zipAlignEnabled true
// 移除無用的resource文件
shrinkResources true
......
}
9.使用ReDex優化
ReDex是Facebook開源一個減小安卓app大小以提高性能的工具,內嵌以及清除僵尸代碼這樣的優化來減小字節碼,主要是對Dex進行了優化,能讓APK 運行更快,不過需要多測試是否會崩潰。
經過 Redex 轉換后的 APK,體積變得更小,運行速度變得更快。Redex 基于管道的方式來優化 Android 的 .dex 文件,一個源 .dex 文件通過管道進行一系列的自定義轉換后,將得到一個優化的 .dex 文件。
我們知道 Android 的編譯過程首先是通過 javac 工具將 .java 文件編譯成 .class 文件,接著將所有的 .class 文件合并成 Dalvik 虛擬機的可執行文件 .dex,最后再跟其他資源等文件一起壓縮成 APK 文件,大致流程如下所示:
轉換的時機
Redex 選擇基于字節碼文件而不是 Java 源碼進行優化,是因為字節碼相比 Java 源碼而言,可以進行更為全局的,類與類之間的優化,而不是單個類文件的局部優化;選擇基于 dex 字節碼而不是 Java 字節碼進行優化,是因為某些優化只能在 dex 文件中進行。
管道的思想
鑒于隨著時間的推移,開發人員可能會不斷得到新的優化 idea,為了方便的將新的優化點加入既有的代碼中,同時也方便不同開發人員并行開發優化點, 所以 Redex 選擇基于管道的思想來實現 dex 的優化,這樣每一個優化的 idea 可以通過插件的形式集成到管道中,實現即插即用,也不會影響其他的優化插件,整體優化流程如下所示:
github地址:https://github.com/facebook/redex