I am trying to build Multidex apk in eclipse, and not able to succeed.
I tried following steps, for configuring Multidex support in android app:
I have added the Multidex library located at /extras/android/support/multidex/ to my project.
As my app is having custom application class, I have extended android.support.multidex.MultiDexApplication Class to my application.
Still i am not able to build apk.
Android developer is also not having any documentation for building Multidex apk in eclipse, its only having documentation for gradle and Android Studio.
You have to modify build.gradle to add multiDexEnabled true under buildconfig, buildType or productFlavour sections
defaultConfig {
// The support library goes as back as Android-14, and is not required for 21+
minSdkVersion 14
// Enabling multidex support.
multiDexEnabled true
}
If you're building on old Ant, this is a blocking problem so you'll have to move to gradle or maven or use the old cumbersome solution
http://android-developers.blogspot.com.es/2011/07/custom-class-loading-in-dalvik.html
Related
We are having problems in building our multidex App. We keep receiving different java.lang.NoClassDefFoundError erros during the application boot.
We noticed that they are very likely related to the multidex issues. As the required classes for booting the App must be present in the primary DEX file and they are not being included in the classes.dex. We performed the steps described in https://developer.android.com/studio/build/multidex.html#keep
but the classes we specify in the multidex-config.txt, or even in the multidex-config.pro are not being placed in the primary dex file (classes.dex).
Do you guys have experience using the multiDexKeepFile or the multiDexKeepProguard? Does it really work? Is there any trick to make it work and place the files in the classes.dex?
Try updating your gradle plugin. I've seen that in 2.2.0 the configuration is ignored entirely. When I updated to 2.3.3 it started respecting the rules I set.
Example:
classpath com.android.tools.build:gradle:2.3.3
And in my default config I have this set:
multiDexEnabled true
multiDexKeepProguard file('proguard.multidex.config')
Also you may have to do a clean build before the changes are reflected.
I have the same problem.And i still don't know why.
But i found another solution,and it works.
In your app module's build.gradle add dexOptions:
android {
dexOptions {
additionalParameters = ['--multi-dex',
'--set-max-idx-number=60000',
'--main-dex-list='+projectDir+'/your_multidexconfig.txt',
'--minimal-main-dex'
]
}
}
You should check your minSdkVersion, if your minSdkVersion is >= 21, multiDexKeepProguard is not supported. Because the build tools has do the dex split by default.
More details:
https://developer.android.com/studio/build/multidex
I am developing xamarin android app and in this many packages and references are used (Google play services). When I try to build this project I get this error:
java.exe exited with code 2 Trouble writing output: Too many field
references: 81626; max is 65536. You may try using --multi-dex
option
.
You need to enable Mutlidex in your project.
Xamarin.Android supports this since version 5.1:
Multi-dex support can be enabled by using the new $(AndroidEnableMultiDex) MSBuild property, which is also available via Visual Studio and Xamarin Studio.
By enabling multidex , Application will crash on Samsung devices S5,S6,So on.
They have stopped the roll out of the update. So it looks like we are waiting for Samsung to roll out a new OS update with it fixed.
Or find a way to not use multi-dex in your app.
You should add below code to your app gradle file :
defaultConfig {
applicationId 'pkg'
minSdkVersion
targetSdkVersion
versionCode
versionName
// Enable MultiDexing: https://developer.android.com/tools/building/multidex.html
multiDexEnabled true
}
And add this dependency also :
compile 'com.android.support:multidex:1.0.1'
Thanks..!!
Android Studio: 1.3.1 - Gradle Build Plugin: 1.1.2 - Gradle: 1.3.0
On Android Studio, I have an app that runs perfectly fine on Android API22 (Lollipop, on both simulator API22 and Android phone API22, and also works on API 21 - but nothing below API 21).
In my Gradle build file, I have the following:
compileSdkVersion 22
buildToolsVersion "22.0.1"
defaultConfig {
minSdkVersion 17
targetSdkVersion 22
...
compile "commons-io:commons-io:2.4" //IO
So, as I understand it: my app is compiled with the latest API (22) to run on devices from API 17 to API 22 (and 22+ in compatibility mode).
However, when I run the Android app on a API 17 simulator, it crashes during some file copy operations.
Before the crash, dalivkvm complains it cannot find methods.
I/dalvikvm﹕ Could not find method org.apache.commons.io.FileUtils.copyInputStreamToFile,
referenced from method FileCopy.batchCreate
W/dalvikvm﹕ VFY: unable to resolve static method 58205: Lorg/apache/commons/io/FileUtils;
.copyInputStreamToFile (Ljava/io/InputStream;Ljava/io/File;)V
D/dalvikvm﹕ VFY: replacing opcode 0x71 at 0x0058
Then the fatal exception:
E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.NoClassDefFoundError: org.apache.commons.io.FileUtils
Now obviously the apache commons libraries can be present and imported, at least on API 22 (which, I remind you, runs successfully on both the device and the simulator).
This also happens for other libraries aside from the Apache commons one (if I skip using the Apache Commons, then another third party library will cause a similar issue and so on).
I'm at loss as to why it won't run on API 17. Also have the same issues on API 18 and 19, API 20 doesn't exist.
It appears to work correctly on both API 21 and API 22.
I've looked for similar errors on here, but usually it is because people simply forgot to include their jar libs so it didn't help.
UPDATES
MultiDex is enabled. On API 21 (Lollipop) the way multidex is supported has changed (see https://developer.android.com/tools/building/multidex.html). So it might have something to do with this.
Gradle builds Modules in "release mode" when app is in "Debug mode" (Why does Gradle build my module in Release mode when the app is in Debug)
I tried rebuilding, creating a new project with the files to no avail.
The "commons-io:commons-io:xxx" folder is present in the Gradle cache folder.
I was able to fix my own issue.
So essentially, as I understand it (but I don't have time to investigate further), the issue is due to the fact that the way "Multidex" is supported has changed in Android API 21 (aka Android 5.0).
The link: https://developer.android.com/tools/building/multidex.html tells us:
Android 5.0 and higher uses a runtime called ART which natively
supports loading multiple dex files from application APK files.
Now, it would seem that when multidexing and trying to support both "normal DEXing" (before 5.0/API21) and "ART oat files" (the new "DEX" files after 5.0/API21) in the same application you can encounter some issues similar to mine (unable to find some methods before API21 but app working fine on API21 and above).
My app hit the 65k methods limit and I had to support from API17+.
Anyway, the workaround was to disable multidex and use instead minifyEnabled with "Proguard", so that all unused methods are removed by Proguard and the total number of methods ends up below 65k.
The associated code (in Gradle build file):
defaultConfig {
...
//Enabling multidex support (for more than 65k methods)
multiDexEnabled false
}
buildTypes {
debug {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
This isn't a real solution, of course, as someone who needs to effectively use 65k methods will HAVE to use multidex, but it did the job nicely for me and I can't spend more time on these issues.
Hopefully this will help someone.
My application has a bunch of librarys that are essential that is why I was forced to use multidex support library and it works nicely. But where the problem shows is in the gradle buid speed. It takes on average 2minutes to build and when I am developing and testing this is quite annoying.
Is there a way to speed up my debug builds?
You can speed-up your development builds by specifying the minimum SDK version = 21.
Official documentation includes a whole section about that.
Example (from documentation):
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'
}
Once you added the product flavors, you can use the devDebug task (instead of default debug task) for your development builds:
- from command line: run ./gradlew installDevDebug
- from Android Studio: open Build Variants window and select the devDebug build variant.
You should, of course, work against a device whose SDK >= 21.
There's also a solution for those who don't want to use flavors. As suggested in this gist, dynamically calculate the minSdkVersion value:
int minSdk = hasProperty('devMinSdk') ? devMinSdk.toInteger() : 14
apply plugin: 'com.android.application'
android {
...
defaultConfig {
minSdkVersion minSdk
...
}
}
In this example, we're checking if devMinSdk property defined, and if true - we're using it. Otherwise, we default to 14.
How do we pass devMinSdk value to build script? Two options:
Using command line:
./gradlew installDebug -PdevMinSdk=21
Using Android Studio preferences:
Go to Preferences (Settings on Windows) -> Build, Execution, Deployment -> Compiler -> put -PdevMinSdk=21 in Command-line Options text box.
Recently build cache was introduced by team working on Android Gradle plugin. You can enable it by adding android.enableBuildCache=true to gradle.properties.
More info here
http://tools.android.com/tech-docs/build-cache
For me it increased incremental build times by ~30 seconds.
It doesn't work with legacy multidex (com.android.support:multidex) introduced as part of support library, so it's suitable only if your minSDK >= 21. You can set it only for your your development builds and do release builds with minSDK < 21.
It also works without multidexing enabled.
Android Studio 1.3 (currently in Preview 3) is using a new build system which improved gradle build time (really, like 10-30x faster).
More information in the Live Session at Google I/O 2015
Multidexing uses more memory. As you get closer to your max heap size in Java you'll find Java spends more time doing GC than it does doing any real work, this can slow things down a lot.
I'd strongly recommend increasing the max heap size when using multidex. Add the following to the android closure in your build.gradle file to make the max heap size 4GB (Make it smaller if you wish):
dexOptions {
javaMaxHeapSize "4g"
}
Changing MinSdk to 21 made everything back to normal for me.Now everything compiles in like 6s
This is no longer needed with the latest Android Studio 3.0
Go in setting , search compiler , type "--offline" in Command line options and than compile.
I have an Android project targetting the Android SDK v21. Now I need to debug it on a device with Android 4.4 (i.e. SDK v20). How do I tell Android Studio to attach an older version of the source to the internal classes so that I can step through them?
Here the best solution is to set compile SDK version to 20. So that build tools will compile your project using SDK version 20 and you can debug your app.
When you use several modules in your project you need to set same compile SDK version to each module.
I can not confirm my answer works, but it is working for me.
I replace my compileSdkVersion, buildToolsVersion, minSdkVersion and targetSdkVersion with new one like following in my build.gradle file.
android {
compileSdkVersion 22
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "com.example.mytest"
minSdkVersion 15
targetSdkVersion 22
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
After changing it, you may not need to convert old to new or new to old sdk component.
You need to open module settings (Right click on your app module and select Open Module Settings or just select module and press ⌘ + ↓ on Mac)
And select compileSdk and buildTools to v20
Another way to do it is to open build.gradle file for the "app" module to change compileSdk and buildTools.
I would like to explain little before the solution.
Google provides the SDK APIs in the form of JAR (android.jar) files. The JAR files are stored at SDK LOCATION\platforms\android-API#.
For example the android.jar file for the Android 4.4(Kitkat) API-19 is located at YOUR SDK LOCATION\platforms\android-19\android.jar.
The Gradle compilation with the Android Studio uses the compileSdkVersion field in the build.gradle to select a specific android.jar for the compilation.
What is compileSdkVersion?
The version of the API the app is compiled against.
This means you can compile and use Android API features included in that version of the API
All the previous version features are also included during compilation.
If you try and use API 21 feature, such as public void openCamera (String cameraId, CameraDevice.StateCallback callback, Handler handler)
Added in API level 21 but set compileSdkVersion to 20, you will get a compilation error.
If you set compileSdkVersion to 21 you can still run the app on a API 20 device as long as your app's execution paths do not attempt to invoke any APIs specific to API 21.
How to set compileSdkVersion?
There are two ways
1. Selecting API from the GUI
1) Select "File->Project Structure..."
2) Select "app->Properties"
3) Set the "Compile Sdk Verion" from the drop down box to the required SDK version.
4) "compileSdkVersion" will be set automatically in the "app" module's
"build.gradle" file.
2. Setting the API in the gradle.build file
1) Open the build.gradle file of the "app" module
2) Set the compileSdkVersion to required value such as 19 for the API#19.
I hope that helps...
Happy Coding...
The best solution for me was to add a new module (Android Library) to the project and set the compile SDK to the requested api level. That way you can still compile your main app with the original SDK level but still get the sources integrated with your debugging Android version.
You can create a new Android Virtual Device with the preferred API level and debug the application on it.
Simply open module settings and change compileSdk and buildTools to v20