Solution for the ANT Packaging 65536 Problem
During Unity ANT packaging, multiple dex packages can result in the "method count exceeds 65536" error (a single dex package supports up to 65536 methods). See Google website to better understand this problem.
There are two methods to solve this problem:
- Use Gradle packaging and enable the Multidex option. See Google website for specific instructions.
- Manually merge JAR packages and res files and import a
multidex.jar
.
When using an earlier version of Unity that does not support Gradle packaging, use ANT packaging and manually merge the JAR packages and resources. However, the Google website does not currently provide corresponding tools. To solve this problem, Player Network SDK provides the INTLUtils tool to package JAR packages and res files.
Manual Merger Principle
In the Android compilation process, all Java methods are written to dex files. If you do not enable Multidex, there will only be one classes.dex
file in the APK.
After enabling Multidex, Gradle packaging will group Java methods, placing the most important Java methods (those that are required during startup) in dex1 (also called classes.dex) and placing other Java methods in dex2 (classes2.dex), dex3 (classes3.dex), and so on.
In principle, manual merging simulates the grouping method in Gradle packaging.
After simple sorting, the process is as follows:
Group Ant projects.
Divide into group 1, group 2, and so on.Manually merge group 2, group 3, and other groups into dex2, dex3, and so on.
Place group 1 in Unity.
Use Unity to package the group and output the APK.
Merge dex2, dex3, and so on into the APK.
Re-sign the APK.
Merger Process
ANT projects do not only contain Java methods but also AndroidManifest.xml
files and res files. These files must also be packaged into the APK by using Unity.
INTLUtils provides functions including:
Merge the JAR packages of all Ant projects into a dex file
Merge the AndroidManifest.xml files of all Ant projects
Merge the res files of all Ant projects
After organizing the files, the process for merging the AndroidManifest.xml
files and res files is as follows:
Group Ant projects. Divide into group 1, group 2, and so on.
Place all the groups except group 1 together, merge the AndroidManifest.xml and res files, and copy the merged files to group 1.
Manually merge group 2, group 3, and other groups into dex2, dex3, and so on.
Place group 1 in Unity.
Use Unity to package the files and output the APK.
Merge dex2, dex3, and so on into the APK.
Re-sign the APK.
Operation Guide
Copy the packages to be merged to the INTLUtils directory
Do the following:
Configure the primary
AndroidManifest.xml
file.The manifest property in the primary AndroidManifest.xml file must contain the property
xmlns:tools="http://schemas.android.com/tools"
, andpackage
must be changed to the name of the demo package.Copy external layer JAR packages to the libs directory.
The libs directory serves as the primary JAR directory of Unity and is packaged with group 1.
Package the
multidex-1.0.3.jar
file to the libs directory and place the multidex file in dex1.
Ant Grouping
Place the external layer AndroidManifest.xml
file and libs directory in group 1. Other projects can be placed in any group following a simple grouping rule of creating 4 MB
groups (not including the .so file size which may reach several MB each and does not affect the Java method count). Ensure that a single dex file does not contain more than 65536 methods.
The group quantity is determined by the method count.
Merge AndroidManifest and resource except group 1
Place all the groups except for group 1 together, such as group 2 and group 3.
Copy the
AndroidManifest.xml
file from group 1 to the groups outside branch 1 (in order to write theAndroidMainfest.xml
files in other groups to the primaryAndroidManifest.xml
file) and create the libs folder.Use INTLUtils to merge
AndroidManifest.xml
and res files.java -jar INTLUtils.jar -unityRoot ./2-5 -buildTools /Users/lucasfan/Library/Android/sdk/build-tools/28.0.3 -output ./output2-5
Copy the generated
AndroidManifest.xml
and res files to group 1.
Generate dex2,dex3,...
Add a blank
AndroidManifest.xml
and libs folder in each group.The manifest property in the AndroidManifest.xml file must contain the property
xmlns:tools="http://schemas.android.com/tools"
, andpackage
must be changed to the name of the demo package.Use INTLUtils to merge Java methods.
java -jar INTLUtils.jar -unityRoot ./2 -buildTools /Users/lucasfan/Library/Android/sdk/build-tools/28.0.3 -output ./output2
Place group 1 back in Unity
Use Unity to package an Android APK
Merge dex2, dex3, and so on into the APK
The names of dex files generated by the tool are in the format classes2.dex
, classes3.dex
, and so on.
Use aapt to merge dex files into the APK.
aapt a test.apk classes2.dex
Place the APK and dex files in directories at the same level. This ensures that the dex files are added to the root directory of the APK.
Re-sign the APK
apksigner sign --ks debug.keystore --ks-key-alias XXXX --ks-pass pass:XXXX --key-pass pass:XXXX -out test-signed.apk test.apk
Note that, if the password contains special characters such as exclamation points (!), add \
before these characters, for example, --ks-pass pass:\!1234
.
INTLUtils Parameter Description
-mainProject, the main project. It does not have to be configured when unityRoot has been set.
-subProject, the subproject(s), with multiple projects separated by commas. It does not have to be configured when unityRoot has been set.
-buildTools, Android build tools directory (required).
-output, the output directory (optional).
-package, the target package name (optional). Set to the main project's package name by default.
-unityRoot, the standard Android Unity project directory (optional). Setting this parameter is equivalent to setting both -mainProject and -subProject.
-useD8, whether to use the D8 compiler (optional). The DX compiler is used by default. Set to
1
to enable the D8 compiler.-androidJar, the
android.jar
path of the Android SDK, is required when the D8 compiler is used. Path:android_sdk/platforms/api-level/android.jar
.
FAQs
A JAR that depends on JDK1.8 failed to generate a dex file
When you use the DX tool to compile a JAR file and generate a dex file, you will see an error message like the one below:
: invalid opcode ba - invokedynamic requires --min-sdk-version >= 26 (currently 13)
This occurs because the JDK1.8 JAR packages generated by DX cannot be converted to dex files. Use the D8 compiler instead.
Set useD8
to 1
and set androidJar
to enable the D8 compiler.