Reputation: 2150
For the last few days I've been unable to run cordova run android
(or rather, ionic run android
) to test my Ionic app on my native device. When I run the command, I get the usual metric ton of output, along with 100% CPU usage from several Java Runtime processes, then the build finally fails with the stated in the title. The console shows this (truncated, as there's a ton of output):
:compileDebugNdk UP-TO-DATE :compileDebugSources
:transformClassesWithDexForDebug UNEXPECTED TOP-LEVEL EXCEPTION:
com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536
at com.android.dx.merge.DexMerger$6.updateIndex(DexMerger.java:484) at com.android.dx.merge.DexMerger$IdMerger.mergeSorted(DexMerger.java:261) at com.android.dx.merge.DexMerger.mergeMethodIds(DexMerger.java:473) at com.android.dx.merge.DexMerger.mergeDexes(DexMerger.java:161) at com.android.dx.merge.DexMerger.merge(DexMerger.java:188) FAILED
BUILD FAILED
Total time: 1 mins 40.116 secs
at com.android.dx.command.dexer.Main.mergeLibraryDexBuffers(Main.java:504) at com.android.dx.command.dexer.Main.runMonoDex(Main.java:334) at com.android.dx.command.dexer.Main.run(Main.java:277) at com.android.dx.command.dexer.Main.main(Main.java:245) at com.android.dx.command.Main.main(Main.java:106)
FAILURE: Build failed with an exception.
What went wrong: Execution failed for task :transformClassesWithDexForDebug.
com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException:
Process 'command 'C:\Program Files\Java\jdk1.8.0_73\bin\java.exe'' finished with non-zero exit value 2
Try: Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Error: Error code 1 for command: cmd with args: /s,/c,"E:\Documents\GitHub\app.auroras.live\platforms\android\gradlew cdvBuildDebug -b E:\Documents\GitHub\app.auroras.live\platforms\android\build.gradle -PcdvBuildArch=arm -Dorg.gradle.daemon=true -Pandroid.useDeprecatedNdk=true"
I just went and updated any necessary tools and libraries in the Android SDK, then I removed and re-added the Android platform (cordova platform add android
), making sure to check that all the relevant platform files were gone, and the project still fails to build.
EDIT: I also ran cordova clean
, but that didn't work. It looks like the Google Play Services library is causing my app to hit the 64,000 method limit, but other than manually tweaking my gradle file (which I'm not au fait with yet), I'm not sure how I can shrink that down
EDIT 2: I tried tweaking my build.gradle file to remove the reference to "com.google.android.gms:play-services:+" (which I think is pushing my app above the 65535 method limit) but it just keeps coming back.
I also tried a build-extras.gradle to remove the dependency, but got another error. Ideally I'd like an answer that doesn't require constant re-working every time I want to build my app, but at this stage I'm keen for pretty much anything.
I did recently upgrade cordova, ionic and bower (using npm install -g cordova ionic bower
after something went screwy with my %PATH% variable on Windows, but I wouldn't imagine that would break anything.
I'm running Windows 10, x64. java -version
reports:
java version "1.8.0_73"
Java(TM) SE Runtime Environment (build 1.8.0_73-b02)
Java HotSpot(TM) 64-Bit Server VM (build 25.73-b02, mixed mode)
Any suggestions?
Upvotes: 2
Views: 2092
Reputation: 11935
Modifying build.gradle
directly is not advisable as the changes will be overwritten after building android platform. Any extensions to build.gradle should be done by adding additional file like 'build-extras.gradle' as suggested in official documentation. As suggested by Grayda, the cleaner solution is to use the plugin which does the job like charm.
Came across one more cordova multiplex plugin which does the job and which is active. You can install the plugin using following command:
cordova plugin add https://github.com/solent/cordova-plugin-multidex
Posting the answer as it may benefit someone out there.
Upvotes: 4
Reputation: 2150
In addition to @SkyWalker's answer, I discovered a Cordova multidex plugin that is a lot "cleaner" (that is, no manual modification to your build.gradle
files).
You simply install it with cordova plugin add --save https://github.com/jwall149/cordova-multidex
and on next build, multidex will be enabled, which will resolve this issue.
Upvotes: 3
Reputation: 29150
:transformClassesWithDexForDebug UNEXPECTED TOP-LEVEL EXCEPTION:
com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536
This message sounds like your project is too large.
You have too many methods. There can only be 65536 methods for dex.
Since the gradle plugin 0.14.0
and the Build Tools 21.1.0
you can use the multidex
support.
Just add these lines in the build.gradle
:
android {
defaultConfig {
...
// Enabling multidex support.
multiDexEnabled true
}
...
}
dependencies {
compile 'com.android.support:multidex:1.0.0'
}
Also in your Manifest add the MultiDexApplication class from the multidex support library to the application element
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.multidex.myapplication">
<application
...
android:name="android.support.multidex.MultiDexApplication">
...
</application>
</manifest>
If you are using a own Application class, change the parent class from Application to MultiDexApplication.
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
Google Play services and DEX method limits
Configuring Your App for Multidex with Gradle
The routine builds performed as part of the development process with multidex typically take longer and can potentially slow your development process.
In order to mitigate the typically longer build times for multidex output, you should create two variations on your build output using the Android plugin for Gradle productFlavors: a development flavor and a production flavor.
The following build configuration sample demonstrates the how to set up these flavors in a Gradle build file:
android {
productFlavors {
// Define separate dev and prod product flavors.
dev {
// dev utilizes minSDKVersion = 21 to allow the Android gradle plugin
// to pre-dex each module and produce an APK that can be tested on
// Android Lollipop without time consuming dex merging processes.
minSdkVersion 21
}
prod {
// The actual minSdkVersion for the application.
minSdkVersion 14
}
}
...
buildTypes {
release {
runProguard true
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro'
}
}
}
dependencies {
compile 'com.android.support:multidex:1.0.0'
}
Upvotes: 4