性能優化專題九--應用包體縮減實戰

首先推薦兩個性能優化的最佳指南一個是官方指南--性能--縮減應用體量,另外一個是Android studio的官方指南--配置編譯版本--壓縮您的應用。涵蓋了壓縮應用體積的所有方面,

官網:https://developer.android.google.cn/topic/performance/reduce-apk-size

AS:https://developer.android.google.cn/studio/build/shrink-code

下面針對幾個比較實用的。我們挑選出來我們實戰下。

1、移除未使用的備用資源

Gradle 資源縮減器只會移除未由您的應用代碼引用的資源,這意味着,它不會移除用於不同設備配置的備用資源。如有必要,您可以使用 Android Gradle 插件的 resConfigs 屬性來移除應用不需要的備用資源文件。

例如,大部分應用其實並不需要支持幾十種語言的國際化支持,如果您使用的是包含語言資源的庫(如 AppCompat 或 Google Play 服務),則您的 APK 中將包含這些庫中消息的所有已翻譯語言的字符串,而無論應用的其餘部分是否翻譯爲相同的語言。如果您只想保留應用正式支持的語言,則可以使用 resConfig 屬性來指定這些語言。系統會移除未指定語言的所有資源。

以下代碼段展示瞭如何設置只保留英語和法語的語言資源:

android {
        defaultConfig {
            ...
            resConfigs "en", "fr"
        }
    }
    

優化前有82個語言285.7KB大小:

優化過後,就只剩英文一種大小爲221.8KB

2、壓縮圖片

  • 2.1使用webP格式

WebP 格式提供有損壓縮(如 JPEG)以及透明度(如 PNG),與 JPEG 或 PNG 相比這種格式可以提供更好的壓縮效果。

webp支持透明度,壓縮比比jpg更高但顯示效果卻不輸於jpg,官方評測quality參數等於75均衡最佳。 相對於jpg、png,webp作爲一種新的圖片格式,從Android 4.0+開始原生支持,但是不支持包含透明度,直到Android 4.2.1+才支持顯示含透明度的webp,使用的時候要注意。

可以使用 Android Studio 將現有 BMP、JPG、PNG 或靜態 GIF 圖片轉換爲 WebP 格式。如需瞭解詳情,請參閱使用 Android Studio 創建 WebP 圖片。將所有圖片轉化爲webp,選中圖片文件夾,右鍵選中Convert to WebP即可

      

完成後可以到減小了100多KB,因爲圖片較少,所以效果可能沒有那麼明顯,但是對原始圖片的壓縮率是很大的,達到了90%左右

原始:   轉化webp:

  • 2.2使用tinypng有損壓縮

 android打包本身會對png進行無損壓縮,所以使用像tinypng這樣的有損壓縮是有必要的。 重點是Tinypng使用智能有損壓縮技術,以儘量少的失真換來圖片大小的銳減,效果非常好,強烈推薦。 Tinypng的官方網站:http://tinypng.com/

  • 2.3使用jpg格式

如果對於非透明的大圖,jpg將會比png的大小有顯著的優勢,雖然不是絕對的,但是通常會減小到一半都不止。 在啓動頁,活動頁等之類的大圖展示區採用jpg將是非常明智的選擇。

  • 2.4使用矢量圖形 

可以使用矢量圖形創建與分辨率無關的圖標和其他可伸縮媒體。使用這些圖形可以極大地減少 APK 佔用的空間。 矢量圖片在 Android 中以 VectorDrawable 對象的形式表示。藉助 VectorDrawable 對象,100 字節的文件可以生成與屏幕大小相同的清晰圖片。

不過,系統渲染每個 VectorDrawable 對象需要花費大量時間,而較大的圖片則需要更長的時間才能顯示在屏幕上。因此,請考慮僅在顯示小圖片時使用這些矢量圖形。如需詳細瞭解如何使用 VectorDrawable 對象,請參閱使用可繪製資源

  • 2.5縮小大圖

如果經過上述步驟之後,你的工程裏面還有一些大圖,考慮是否有必要維持這樣的大尺寸,是否能適當的縮小。 事實上,由於設計師出圖的原因,我們拿到的很多圖片完全可以適當的縮小而對視覺影響是極小的。

  • 2.6覆蓋第三庫裏的大圖

有些第三庫裏引用了一些大圖但是實際上並不會被我們用到,就可以考慮用1x1的透明圖片覆蓋。 你可能會有點不舒服,因爲你的drawable下竟然包含了一些莫名其妙的名稱的1x1圖片

3、so庫優化,只保留armeabi-v7a

在使用一些三方庫的時候,會集成大量的so文件到項目中,這些so文件都對應着不同的CPU架構。Android系統目前支持以下七種不同的CPU架構:ARMv5、ARMv7、x86、MIPS、ARMv8、MIPS64、x86_64,每一個CPU架構對應一個ABI:armeabi,armeabi-v7a,x86,mips,arm64-v8a,mips64,x86_64。

如果項目中包含第三方SDK或者自己使用了ndk,如果不進行配置會打包全cpu架構的動態庫進入apk。目前市面上絕大部分的CPU架構都是 ARMv7/ARMv8,所以可以在gradle中加入配置,只保留v7,v8。對於真機,只需要保留一個armeabi(armeabi-v7a)就可以了,微信大佬就這麼幹的!這裏不排除有極少數設備會Crash,可能和不同的so有一定的關係,請大家務必測試周全後再發布

原始gradle配置裏面添加了較多的架構:

    ndk {
            //設置支持的SO庫架構
            abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
        }

可以看到so的體積佔用了apk體積的70%,我們手機絕大多數都是ARM架構,所以不需要添加這麼多架構的so 

我們改爲ARM64:

    ndk {
            //設置支持的SO庫架構
            abiFilters "armeabi-v7a"
        }

可以看到包體減少了55%,從原來的22MB減少到9.9MB,效果是非常明顯的

4、使用Lint檢測

在Analyze中:

        

將檢測出來沒有被引用到的資源文件刪除掉即可,但是需要注意提前備份,以防無法回退回來。lint檢測可以避免刪除掉反射使用的資源,因此是較爲安全的方式。

按照這種方式完成後,apk大小從9.9MB縮小到了9.8MB:

注意:lint 工具不會掃描 assets/ 文件夾、通過反射引用的資源或已鏈接至應用的庫文件。此外,它也不會移除資源,只會提醒您它們的存在。 

5、開啓混淆

Android代碼混淆,又稱Android混淆,是一種Android APP保護技術,用於保護APP不被破解和逆向分析。
ProGuard的三大作用

  • 壓縮:移除未被使用的類、屬性、方法等,並且會在優化動作執行之後再次執行(因爲優化後可能會再次暴露一些未被使用的類和成員。
  • 優化:優化字節碼,並刪除未使用的結構。
  • 混淆:將類名、屬性名、方法名混淆爲難以讀懂的字母

6、開啓刪除無用資源(與Lint不同)

debug {
            shrinkResources true
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }

shrinkResources 用來開啓壓縮無用資源,也就是沒有被引用的文件(經過實測是drawable,layout,實際並不是徹底刪除,而是保留文件名,但是沒有內容),但是因爲需要知道是否被引用所以需要配合mififyEnable使用,只有當兩者都爲true的時候纔會起到真正的刪
除無效代碼和無引用資源的目的。與去除無用資源不同的是,比如某個java類沒有用到,被混淆時刪除了,而該類引入了layout資源 ,此時會將這個資源也壓縮掉。

使用混淆最重要是需要配置混淆keep文件,完成後看下效果,包體從9.8MB減少到了7.7MB,效果還是很明顯的:

具體我們來看下他是怎麼縮小包體的:

打開資源文件xml可以看到後面有很多47B大小的佈局文件:

這時我們隨便找一個toast_layout.xml看下源文件和優化後的文件對比:

優化後:

優化前:

再看一個layout_pupup.xml對比:

優化後:

優化前:

可以看到,原來是將沒有用到的文件在編譯時,通過簡單的字符替換掉了,而不是簡單粗暴的將源文件刪除掉,因此大大降低了包體大小

對比lint而言,lint的代碼檢測會直接將無用的資源文件以及ID刪除掉,因此使用lint優化無用資源時需要提前備份好數據,以免無法恢復。

7、自定義要保留的資源

如果您有想要保留或捨棄的特定資源,請在項目中創建一個包含 <resources> 標記的 XML 文件,並在 tools:keep 屬性中指定每個要保留的資源,在 tools:discard 屬性中指定每個要捨棄的資源。這兩個屬性都接受以逗號分隔的資源名稱列表。您可以將星號字符用作通配符。

例如:

    <?xml version="1.0" encoding="utf-8"?>
    <resources xmlns:tools="http://schemas.android.com/tools"
        tools:keep="@layout/l_used*_c,@layout/l_used_a,@layout/l_used_b*"
        tools:discard="@layout/unused2" />
    

將該文件保存在項目資源中,例如,保存在 res/raw/keep.xml。構建系統不會將此文件打包到 APK 中。具體見官網

https://developer.android.google.cn/studio/build/shrink-code

具體使用方式,在raw下新建:keep.xml。裏面填寫不需要混淆的xml文件名稱即可。

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
    tools:keep="@layout/base_*" />
    <!--tools:keep="strict"-->

完成後上面toast_layout.xml以及layout_pupup.xml,就不會被X佔位符替代掉了。

8、在 Android Studio 中使用 Android Size Analyzer

安裝Android Size Analyzer插件,安裝插件後,從菜單欄中依次選擇 Analyze > Analyze App Size,對當前項目運行應用大小分析。分析了項目後,系統會顯示一個工具窗口,其中包含有關如何縮減應用大小的建議

9、避免使用枚舉

單個枚舉會使應用的 classes.dex 文件增加大約 1.0 到 1.4KB 的大小。這些增加的大小會快速累積,產生複雜的系統或共享庫。如果可能,請考慮使用 @IntDef 註釋和代碼縮減移除枚舉並將它們轉換爲整數。此類型轉換可保留枚舉的各種安全優勢。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章