啟用MultiDex解決Unity2019.3.x構建Android遊戲64K引用限制問題

今天抽空將項目的Unity版本升級到了2019. 3.6f ,畢竟是大版本升級,做好了心理準備要對編譯環境和代碼做一次大調整的,意料之外還頗為順利,只踩了2~3個小坑,這裡記錄下其中的一個,如果你也遇到相同的問題,希望本文可以有所幫助。


問題:Jenkins在構建Android遊戲時報dex 64k引用錯誤:

<code>stderr[
D8: Cannot fit requested classes in a single dex file (# methods: 93859 > 65536)

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':launcher:transformDexArchiveWithExternalLibsDexMergerForRelease'.
> com.android.builder.dexing.DexArchiveMergerException: Error while merging dex archives:
The number of method references in a .dex file cannot exceed 64K./<code>

熟悉Android開發的同學對這個錯誤應該不陌生,Android 5.0之前的版本(API level < 21)使用Dalvik runtime 來執行代碼,默認限制每個APK 只能使用一個classes.dex 文件,而DEX規範又將單個DEX文件內引用的方法總數限制為65536個,所以如果你遊戲中使用了較多的第3方SDK,很容易就會超過這個限制。

這個問題我們之前也遇到過,解決的方法有三種:

(1)在Player Settings中將支持的最低Android API 級別設定為21及以上。Android API Level 21及更高版本支持從APK文件中加載多個DEX文件,因此不會受64K的限制。

(2)使用Custom Gradle 配置文件並啟用MultiDex支持(在PlayerSettings>Publish Settings>Build 設置中勾選Custom Gradle Template,然後修改項目目錄Assets/Plugins/Android/mainTemplate.gradle啟用MultiDex支持)

(3)修改Unity Editor 默認的Gradle配置文件並啟用MultiDex支持(Unity安裝目錄/PlaybackEngines/AndroidPlayer/Tools/GradleTemplates/mainTemplate.gradle)

我們項目之前使用的是第(3)種方法,即修改Unity Editor默認的Gradle配置文件mainTemplate.gradle,啟用MultiDex,這種方法的好處是多個項目可以共享這個配置,壞處是每次升級Unity時都要重新修改一次。

於是我們按之前的方法修改了Unity3.6f的mainTeamplate.gradle文件並重新編譯,但發現問題依然存在,經上網搜索查詢後發現:原來在Unity3.x以上版本中,Unity增加了baseProjectTemplate.gradle 和 launcherTemplate.gradle 兩個配置文件(我還搞不清楚增加的這兩個配置文件的具體作用是什麼,猜想launcherTemplate.gradle可能是用於構建獨立應用時使用的,哪位同學如果知道還請賜教)。修改launcherTemplate.gradle啟用MultiDex後,編譯順利通過。

下面是分別在Unity 2019.3.x之後及之前的版本中啟用MultiDex的方法:

(1)在Unity 2019.3.x之後的版本(以2019.3.6f版本為例) ,修改
/Applications/Unity/Hub/Editor/2019.3.6f/PaybackEngines/AndroidPlayer/Tools/GradleTemplate/launcherTemplate.gradle

(2)在Unity 2019.3.x之前的版本(以2019.2.12f版本為例),修改
/Applications/Unity/Hub/Editor/2019.2.12f/PaybackEngines/AndroidPlayer/Tools/GradleTemplate/mainTeamplate.gradle

兩個版本的配置文件,需要修改的地方都是相同的,如下:

第一步、在defaultConfig配置塊中,增加“multiDexEnabled true”

<code>android {
defaultConfig {
...
multiDexEnabled true
minSdkVersion **MINSDKVERSION**

targetSdkVersion **TARGETSDKVERSION**
...
}
...
}/<code>

第二步、如果你的項目沒有使用AndroidX,那麼添加以下支持庫依賴項:

<code>dependencies {
implementation 'com.android.support:multidex:1.0.3'
}/<code>

如果項目使用了AndroidX,那麼添加下面的支持庫依賴項

<code>dependencies {
implementation 'androidx.multidex:multidex:2.0.1'
}/<code>

第三步、修改位於項目目錄Asset/Plugins/Android/的AndroidManifest.xml文件,設置<application> 標記中的 android:name,如下所示:/<application>

<code>   
<manifest> package="com.example.myapp">
<application> android:name="android.support.multidex.MultiDexApplication" >
...
/<application>
/<manifest>/<code>

第四步、如果你的項目替換了Application類,那麼還要更改這個類,添加擴展以支持MultiDexApplication

<code>public class MyApplication extends MultiDexApplication { ... }/<code>

更多可以參考Google官方的設置建議:https://developer.android.com/reference/androidx/multidex/MultiDexApplication

Unity Forum上對這個問題的討論:
https://forum.unity.com/threads/cant-build-with-multidex-enabled.773348/


分享到:


相關文章: