APK體積優化的一些總結

筆墨Android發表於2019-05-11

面對那種無節操的產品,你們怎麼辦?

產品:“apk的體積是否可以優化以下,這樣比較好推廣!”

我:“不可以!”

產品:“apk的體積是否可以優化以下,這樣比較好推廣!”

我:“不可以!”

產品:“apk的體積是否可以優化以下,這樣比較好推廣!”

我:“我考慮一下!”

沒辦法面對這樣的產品我們怎麼能慫!老子寫程式碼都是一把梭!!!

但是回頭想想,這個和寫程式碼有個毛線關係!!!

好了,吐槽環節到此結束!!!

今天我們就來討論一下,apk體積優化的一些方式:

本文知識點:

apk優化的一些奇淫技巧!!!

本文分為如下幾個步驟去優化,有什麼不對的還請大神們見諒!小弟還是個菜鳥。。。 哈哈 !!

  1. svg的使用與優化
  2. Tint著色器的使用與優化
  3. 資源打包配置優化
  4. 動態庫的打包配置優化
  5. 移除無用的資源(物理與非物理刪除)
  6. 程式碼混淆
  7. webp轉換(api等級18)
  8. 資源混淆

這個需要api的等級最低為18,現在基本上都可以滿足需求!

這個使用的時候很簡單,選中圖片直接右鍵,conver to Webp...直接就能轉換過來!越大的圖片轉換節約的體積也就越大! 8. 資源混淆

基本上我優化的時候就從以上幾個方面去進行的,在和之前沒進行優化的專案比較,可以使體積減少至少30%!不信可以在你的專案中實驗一下!省的說我開車不穩,翻車了!!!

1. svg的使用與優化

首先我們先來了解一下什麼是svg在百度百科是這麼說的!!!,其實我們只要關注主要的概念就好了!可縮放的向量圖形。其實人話就是在不同大小的地方顯示不變形!具體的概念,看看百度百科就好了!!!

為了方便給大家演示!這裡呢?我特意找了個網站阿里向量圖,在這個網站中你可以下載各種的向量圖,然後呢?就沒有然後了。。。

下載之後呢?會有一個醜醜的ie瀏覽器的圖示字尾為.svg的東西!這個怎麼用呢?強大的android studio 為我們做好了準備工作!

res->new->vector Asset

展示效果圖

之後會蹦出來這麼個玩意

展示效果圖

前一個紅框是系統的圖示,後一個是本地的圖示!這樣你就會生成一個以.xml為結尾的圖示了!

裡面的程式碼大概是這個樣子的!

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24.0"
    android:viewportHeight="24.0">
    <path
        android:fillColor="#FF000000"
        android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z" />
</vector>
複製程式碼

其實裡面的具體語法我也不太瞭解,應該是在指定區域中分成寬和高的等份,然後填充的!感興趣的可以自己瞭解一下!

使用的話,和之前的src不同了!必須這樣使用!

app:srcCompat="@drawable/ic_arrow_back_black_24dp" 
複製程式碼

這裡很多人會有兩個疑問?

  • 這個和apk體積優化有個毛線關係?
  • 美工往往給很多張圖片,總不能一張一張轉換吧?

關於上面這兩個問題,我們分別來說一下:

  1. 首先svg是可縮放向量圖,所以呢?你在專案中只要新增一張svg就可以替換相應的之前美工給你的一套圖,一下減少了好幾張圖片,你說是否有關係呢?其次svg轉換成xml後大小也有相應的縮減,這個真的是成倍減少大的! 但是,但是,但是。。。這個在需要適配,適配,適配!FUCK 0.0!話說Android在適配這點上真心難受!還是看解決辦法吧!在你的app->build.gradle中的defaultConfig標籤中新增如下內容:
        //5.0的相容適配
        //5.0以下 將svg圖片生成指定維度的png圖片,下面寫幾個就會生成幾個相應的圖片
        vectorDrawables.generatedDensities('xhdpi','xxhdpi')
        //5.0以上 以上使用support-v7進行相容
        vectorDrawables.useSupportLibrary = true
複製程式碼

這個是我找到的解決方案,但是我編譯了一下試了試。如果我單寫頂上那一句,會在相應的資料夾下生成出圖片,但是加上後面這句,相應的圖片就沒有了!我就好奇了,為什麼呢?然後我找到了相應的手機試了一下,加不加上面這句沒有什麼卵用!我是在19版本上測試的!找這樣的手機真心費勁,要不是我父母我還真找不到!!!所以呢?大家斟酌一下吧!!!

  1. 這個問題,大神們早就幫我們解決了!!!

下面這個是一個批量轉換工具!話說沒有什麼事情能難倒程式設計師!!!(對我失效)

MegatronKing/SVG-Android 下載這個jar包->svg2vector-cli-1.0.1.jar

然後一波小命令!!!咔咔咔

    java -jar svg2vector-cli-1.0.1.jar -d D:\svg -o D:\vector
    
    -d 指定svg檔案所在目錄
    -f 指定當個svg檔案
    -h 設定轉換後svg高
    -w 設定轉換後svg寬
    -o 輸出android vector影像目錄
複製程式碼

然後轉換完成,然後複製就好了!!!

2. Tint著色器的使用與優化

大家在開發的時候不知道有沒有過這種體驗!在使用狀態選擇器的時候,需要使用兩張一樣顏色不同的相同圖片?其實使用tint屬性完全可以搞定(但是這裡指的是純色的那種圖片,那種花花綠綠的你還是乖乖弄吧,除非你想把他變成純色!)

其實真的很簡單,只要在展示的圖片中新增

app:tint="顏色值"
複製程式碼

這樣就可以改變圖片的顏色,那麼狀態選擇器呢?怎麼用呢?其實很簡單了!下面我們來看程式碼!

先來看看兩個狀態選擇器的程式碼:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/ic_arrow_back_black_24dp" android:state_pressed="true" />
    <item android:drawable="@drawable/ic_arrow_back_black_24dp" android:state_pressed="false" />
</selector>
複製程式碼

可能你會奇怪了,為什麼兩個圖片是一樣的?看到後面你就懂了!

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@android:color/white" android:state_pressed="true" />
    <item android:color="@android:color/black" />
</selector>
複製程式碼

其實原理是這樣的,狀態選擇器的話呢?只要你通過tint的狀態選擇器改變圖片的顏色就可以了!

但是這裡面有幾個點需要注意下:

  1. 顏色的那個狀態選擇器要方法color資料夾下;
  2. 設定tint的時候要使用app為字首,否則5.0以下的會報錯;
  3. 如果你設定的是svg的圖片要使用srcCompat如果是正常圖片使用src就好了。

基本上這層優化就到這裡了!

3. 資源打包配置優化

其實這個標題說的有點大,其實就是刪除不必要的語言!!!

可能你們沒有留意過,在你用Android Studio檢視你的apk的時候,會看到這樣的東西!

效果圖

在我畫框的地方,有很多中語言的使用?你會好奇的問?我沒有設定過語言啊?這都從哪裡跑出來的呢?其實實在v7包中的!其實我們一般的應用不會涉及到這些語言的!所以我們只留下其中的一種或幾種就可以了。具體怎麼做呢?其實就只有一行程式碼。。。

在app的build.gradle中的defaultConfig中新增這樣一句就可以了!

resConfigs('zh-rCN'')
複製程式碼

這裡其實你還可以新增多個,直接用逗號連線就可以了!

優化後就變成下面這個樣子了!!!

效果圖

4. 動態庫的打包配置

其實說到動態庫的話,基本上就是.so引入的動態庫,其實這裡有很大的優化空間!其實你可以解壓比較大型的專案,其實沒有那麼多so檔案的型別!

平時我們開發的時候,基本上都是這麼寫的!

 sourceSets{
        main{
            jniLibs.srcDirs = ['libs']
        }
    }
複製程式碼

然後

ndk{
        abiFIlters('armeabi','armeabi-v7a','xxx'....)
    }
複製程式碼

是不是每次像匯入百度語音等第三方庫的時候,說明文件上這麼寫的我們也就這麼弄的!但是其實我們不需要這麼多的架構!

這裡簡單說一下常用的幾個

armeabi 真機 x86 模擬器

其實我們真是開發的話,直接使用armeabi就可以了,如果你做那種定製化的apk的話,把其它的加上還可以,但是如果正常的手機應用的話,這裡只需要armeabi的就可以了!

如果你怎麼不知道用哪個?你把比較大的專案解壓一下看看人家用哪個你就用哪個!哈哈

5. 移除無用的資源(物理與非物理刪除)

5.1 物理刪除(無法找回,慎用)

關於物理刪除其實很多都不建議這麼使用,因為這個真的沒有什麼節操!這裡說兩個問題:

  • 如果你們專案沒有專案管理的話,真的不建議這麼使用,因為刪除之後你真的找不到了!是真的找不到了(如果git的話,拉個分支使勁磕就可以)!
  • 如果有反射或者動態載入id的(ids.xml)的會直接刪除!可能會報錯!

好了,前提說好了!別到時候後刪了之後找我。。。

方案一: Refactor->Remove Unused Resource... 這裡會談個框,會有三個選項:

  • (Refactor)第一個是直接刪除了
  • (Preview)第二個會在下面彈出一個提醒,讓你選擇性的刪除
  • (Cancel)取消

方案二: Analyze->Run Inspection by name 這裡也會彈出個框輸入 unused ressources 然後又彈出個框,這裡就按照上面的圈圈點點,然後點OK這個時候你會發現底下會出現相應的無用資源這個時候你看哪個不用就直接按照右邊的提示刪除就好了

再次強調,這個是物理刪除,刪除了就沒了!!!

5.2 非物理刪除

其實我估計google爸爸早就考慮到這個問題了,其實還有一種非物理刪除的,是在混淆的時候!相信大家在混淆的時候都寫過這句吧!

shrinkResources true
複製程式碼

開始的時候我也不知道是什麼鬼,後來看別人說這個是啟動資源壓縮!

但是,如果你看過壓縮後的apk的話,這個資源壓縮是使用了一個佔位符而不是把相應的檔案刪除!

其實這個資源壓縮還有一個比較又意思的點,可以自定義要保留的內容:

res->raw->keep.xml 自定義要保留的東西

<resources 
    tools:keep="@layout/activity_main1"   保留誰這裡就可以寫誰
    tools:shrinkMode="strict"/> 
複製程式碼

這個是看谷歌文件中寫的!但是真的不知道為什麼還要保留?處於什麼原因呢?還請懂的大神指點!!!

6. 程式碼混淆

關於這個我不準備在這裡講,程式碼混淆網上一搜一大把!基本上一個固定模板加上你引入的第三方庫的混淆就ok了(注意實體類就好了,每次我都忘)!

7. webp轉換(api等級18)

關於webp百度百科是這麼解釋的。 這個需要api的等級最低為18,現在基本上都可以滿足需求!

這個使用的時候很簡單,選中圖片直接右鍵,conver to Webp...直接就能轉換過來!越大的圖片轉換節約的體積也就越大!直接看相應的轉換就可以了!

這裡我多嘮叨一句,其實有這個圖片壓縮網站還是不錯的!每次美工給我圖片的時候我都會選擇壓縮一下,能節省點體積!關鍵是這個網站可以批量上傳,這個才是重點!然後你再webp就可以了!其實我個人覺得,除非引導圖等...比較大的圖,否則沒有必要使用webp!個人感覺而已。。。

8. 資源混淆

關於資源混淆基本上是美團和微信的兩大方案,我還在整理!

  • 微信的方案開源了!
  • 美團的貌似是沒有開源,但是在相應的技術部落格中寫了

等整理好了之後在貼出來!


基本上我現在的專案體積優化的話,就弄了這麼多,還請大佬們指點!!!

相關文章