Solving Unity multidex issue
A lot of fellow unity developers are stuck at this issue.
CommandInvokationFailure: Unable to convert classes into dex format.
We generally end up with 2 solutions
i) Exporting project as a gradle project. And adding multidex support in the project.
ii) Reducing number of dependency library.
Well I am here to tell you there is one more way (atleast what I researched so far). If you have found it great, if not let’s do explore it together.
Prerequisite
In order to do so, following are the requirement
i) Android studio 2.3.3 (yes you read it right, not 3.0 I would recommend).
ii) Unity 5.6.3 (Any unity version with gradle support).
Steps
i) Creating Unity project.
Honestly any existing project would work. For the sake of simplicity, I am going to create a blank unity project. Lets name it MultidexApplication.
ii) Switching to Android build.
iii) Create android specific project
Let’s create manifest file in folder Assets/Plugins/Android folder
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
package="com.unity3d.player" android:installLocation="preferExternal" android:versionCode="1"
android:versionName="1.0">
<supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true"
android:xlargeScreens="true" android:anyDensity="true"/>
<application
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" android:icon="@drawable/app_icon"
android:label="@string/app_name" android:debuggable="true">
<activity android:name="com.unity3d.player.UnityPlayerActivity" android:label="@string/app_name"
android:screenOrientation="landscape">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<meta-data android:name="unityplayer.UnityActivity" android:value="true"/>
</activity>
</application>
</manifest>
iv) Create a gradle file
a) Unity 2018 or later
Unity 2018 or later now directly provides option to override mainTemplate.gradle. You can enable it by going File->Build Settings->Player Settings in Mac. Go to Publishing Settings and tick “Custom Gradle Template”. You will be able to see mainTemplate.gradle in your Plugins/Android folder.
b) For (Unity 2017 or before)
In order to do so, we would need you to copy mainTemplate.gradle to you android folder.
You can find mainTemplate.gradle file for mac in
/Applications/Unity/PlaybackEngines/AndroidPlayer/Tools/GradleTemplates/mainTemplate.gradle
It would looks like this
// GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAINbuildscript {repositories {jcenter()}dependencies {classpath 'com.android.tools.build:gradle:2.1.0'}}allprojects {repositories {flatDir {dirs 'libs'}}}apply plugin: 'com.android.application'dependencies {compile fileTree(dir: 'libs', include: ['*.jar'])**DEPS**}android {compileSdkVersion **APIVERSION**buildToolsVersion '**BUILDTOOLS**'defaultConfig {targetSdkVersion **TARGETSDKVERSION**applicationId '**APPLICATIONID**'}lintOptions {abortOnError false}aaptOptions {noCompress '.unity3d', '.ress', '.resource', '.obb'}**SIGN**buildTypes {debug {jniDebuggable true}release {// Set minifyEnabled to true if you want to run ProGuard on your projectminifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-unity.txt'**SIGNCONFIG**}}}
I would recommend you to not change anything else, untill you get to understand what it does. So as you can see default gradle version that unity is supporting is 2.1.0. For this reason only I suggested Android studio 2.3.3.
v) Adding Multidex support in template gradle.
Let’s include multidex in out gradle template. In dependencies just add following line before **DEPS**
compile 'com.android.support:multidex:1.0.1'
Enable multidex now in defaultConfig.
defaultConfig {multiDexEnabled truetargetSdkVersion **TARGETSDKVERSION**}
We are almost done from unity side but we are still not over yet.
vi) Creating Android studio project
Create a new project in android studio.
I am going to create new library in this project
Select File->New->New Module->Android library.
Create new class in the library and add following code.
package com.psycodex.core;
import android.content.Context;
import android.support.multidex.MultiDex;
import android.support.multidex.MultiDexApplication;
public class PsycodexApplication extends MultiDexApplication {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
}
You also need to add multidex dependency in gradle file.
vii) Creating aar file for unity
We are going to create aar file from the android library we just created. Select gradle tab from right side and go to core->Tasks->build->assembleRelease.
Now then aar file is created let’s go to core->build->aar->core-release.aar and copy that onto our project’s android folder.
viii) Setting custom application class.
Let’s go back to our manifest file again and set application name to our custom application name.
Now try building your project through unity. It should build project with multidex enabled.
Github link :- https://github.com/iabhipatidar/MultidexProject/tree/master
Conclusion
That’s all you need to do to enable multidex support in unity using gradle.
There are few things worth mentioning.
If you guys have noticed we have included multidex dependency twice (why?). I believe that should not be an issue, gradle will take care of it.
Official statement by Unity for multidex enabling is still NO.
Although it solves multidex issue, working and fixing gradle issues still requires good amount of knowledge.
The good part is you don’t have to export your project again and again, you can directly build multidex game from unity itself.