1. 程式人生 > >Android Gradle Plugin(AGP) 升級 3.0+ ,Gradle升級4.4+過程記錄

Android Gradle Plugin(AGP) 升級 3.0+ ,Gradle升級4.4+過程記錄

一.背景

作為GP開發者,緊跟Google的腳步,升級開發環境和編譯環境,不僅可以提升編譯效率,新工具,新特性也是開發者們所期待的,當然隨著工具的升級App的質量也會提升。所以,專案定期推進技術升級,顯得很有必要。

專案中原有的一些配置

  • Android Gradle Plugin(AGP)版本是2.3.1
  • Gradle的版本為gradle-3.5-all
  • Android Studio(3.1.3)
  • JDK-7

此次的目標是升級到

  • Android Gradle Plugin(AGP)版本是3.1.3
  • Gradle的版本為gradle-4.7-all
  • Android Studio(3.3 Canary 3)
  • JDK-8

二.升級過程中遇到的問題:

整體來說AGP升級有很多需要改變的地方,每個專案中都會踩到不同的坑。所以我只是簡單的從我們專案中遇到的問題介紹一下:

2.1 不在需要configuration傳遞,compiler替換成api或者implementation

  • 升級以後,首先原來的compile變成了apiimplementation(當然還有其他幾個,這裡不細說)簡單的來說,api引進來的元件允許向上傳遞,implementation引入進來的元件,不允許傳遞。其實就是訪問隔離,當然也會提升編譯速度。
  • configuration: 'release'也會自動傳遞。無需在像下面這種寫法來傳遞了。
releaseCompile project(configuration: 'release', path: ':xxx-base-framework')
debugCompile project(configuration: 'debug', path: ':xxx-base-framework')
api project(':xxx-base-framework')

2.2 Dex Knife

因為專案龐大

  • Class的數量2.8萬+
  • Method的數量在17萬+

Dex Knife 主要是解決Gradle2.3版本時,會出現Too many classes in --main-dex-list, main dex capacity exceeded

或者因為被擠出主Dex導致的類或者方法找不到問題。
當然當AGP升級到3.1.3之後,我們關閉了Dex Knife,讓AGP自己去處理分包。效果還不錯。暫時沒出現問題。可能是有優化過吧。

  dexOptions {
    ...
    additionalParameters = [//dex引數詳見 dx --help
                            '--multi-dex', //多分包
                            '--set-max-idx-number=55000', //每個包內方法數上限
                            //'--main-dex-list=' + projectDir +
                            //'/maindexlist.txt', //打包進主classes.dex的檔案列表
                            //'--minimal-main-dex' //使上一句生效
    ...
    ]
  }

同時開啟D8之後,Dex Size從原來的12.4M降低到了11.9M。還是可以的。下面說說D8的BUG吧。

  • Before D8 總計12.4M
    這裡寫圖片描述
  • After D8 總計11.9M
    D8開啟後的大小

2.3 D8 BUG

java.lang.RuntimeException: com.android.builder.dexing.DexArchiveMergerException: Error while merging dex archives: 
app/build/intermediates/transforms/dexBuilder/othersAbroad/release/0.jar, 
app/build/intermediates/transforms/dexBuilder/othersAbroad/release/2.jar,
app/build/intermediates/transforms/dexBuilder/othersAbroad/release/3.jar, app/build/intermediates/transforms/dexBuilder/othersAbroad/release/4.jar

這其實關係到一個流程,AGP先將Java程式碼混淆並編譯成jar包放到上述目錄位置。然後D8會根據maindexlist.txt(app/build/intermediates/multi-dex/othersAbroad/release/maindexlist.txt)裡的配置,編譯成dex檔案。當然配置列表由AGP生成。自己專案中擴充套件的maindexlist.txt一會被追加到上面的這個build目錄中的maindexlist中。

 defaultConfig {
    ...
    multiDexEnabled true
    multiDexKeepFile file('multiDexKeep.txt')
    ...
    }

是因為我在multiDexKeep.txt中的錯誤寫法如下:

com.xxx.xxx.SplashActivity.class
com.xxx.xxx.MainActivity.class

正確寫法:

com/xxx/xxx/SplashActivity.class
com/xxx/xxx/MainActivity.class

開發者網站配置方法數超過 64K 的應用文章中是有提到的,只是在真正build的時候DX是直接忽略掉,D8是提示報錯。但是沒有準確提示。

2.4 aapt2的問題

這個問題很直接

  • 錯誤寫法:
<resources>
  <style name="popup_animation">
    <item name="@android:windowEnterAnimation">@anim/popup_show</item>
    <item name="@android:windowExitAnimation">@anim/popup_hide</item>
  </style>
</resources>
  • 正確寫法:
<resources>
  <style name="popup_animation">
    <item name="android:windowEnterAnimation">@anim/popup_show</item>
    <item name="android:windowExitAnimation">@anim/popup_hide</item>
  </style>
</resources>

好吧,到底改了什麼?把android:windowEnterAnimation 前面的@去掉吧。