multiDexKeepFile not working - android

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

Related

What does 'minifyEnabled=true' do when all configuration options are disabled?

I have a complicated build setup for an android app which basically consists of a normal android app fused together with a Xamarin/Mono project in order to include an important C# library (like this: https://github.com/royd/KotlinAppWithXamarinDependency)
Everything is working fine except if I enable minification in my app/build.gradle via minifyEnabled true the app instantly crashes on startup because the Mono-runtime can't find native assemblies that are definitely contained in the apk.
This is the message I get in Logcat:
A/monodroid: No assemblies found in '(null)' or '<unavailable>'. Assuming this is part of Fast Deployment. Exiting...
With minifyEnabled false everything is working fine so I tried disabling all config options in my proguard-rules.pro:
-dontobfuscate
-dontoptimize
-dontshrink
And I also added the following lines to my app/build.gradle
packagingOptions {
doNotStrip "*/armeabi/*.so"
doNotStrip "*/armeabi-v7a/*.so"
doNotStrip "*/x86/*.so"
}
Unfortunately all this doesn't help.
I also decompiled a working and a broken apk with dex2jar to compare the bytecode. It seems to be exactly the same except for some enum-optimizations that shouldn't matter.
According to the error message in Logcat the error seems to be thrown from the native library libmonodroid.so.
So my question: What does minifyenabled flag do when all these config options are disabled?
Edit:
I have found out that minification works as intended when I use version 4.0.1 of Android Gradle Plugin (from July 2020). Upgrading the version to 4.1.0 (August 2020) breaks my app. Now the question is what changed between these two versions?
When you set the minifyenabled as true. The r8 will choose the configuration files but not only the proguard-rules.pro and the app/build.gradle to shrink, obfuscate, and optimize your app.
There are some others files such as AAR libraries: <library-dir>/proguard.txt and
JAR libraries: <library-dir>/META-INF/proguard/ and so on. So this error may be caused by the native library losing when you set the set the minifyenabled as true.
If you need more information, please check the official document:https://developer.android.com/studio/build/shrink-code#enable
In addition, you can check the 'proguard-android-optimize.txt' and when you add the -dontoptimize to proguard-rules.pro may cause a conflict.
I found out, that in the Android Gradle Plugin versions 3.6.0 to 4.1.0 they switched to a more performant tool for building apks called zipflinger.
This tool can be disabled by adding this line to my gradle.properties:
android.useNewApkCreator=false
When building the apk zipflinger stores the external .NET assemblies as DEFLATED zip entries instead of STORED and thats why monodroid cant read them.
References:
https://github.com/xamarin/xamarin-android/issues/6838#issuecomment-1110816027
https://copyfuture.com/blogs-details/20210119115509664T

After update gradle ver apk size twice bigger, why?

I had gradle
classpath 'com.android.tools.build:gradle:3.5.3'
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
and my apk 160Mb
then I update it to
classpath 'com.android.tools.build:gradle:3.6.3'
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
and my apk size is 270Mb
How is it possible? But acctually if I build .aab it is still has 160Mb, so size increasing if I build .apk
This is caused by a change in the Gradle plugin which used to zip deflate the native libraries, but now just stores them. According to Google this ends up being a benefit for end users:
Smaller app install size because the platform can access the native
libraries directly from the installed APK, without creating a copy of
the libraries.
Smaller download size because Play Store compression is
typically better when you include uncompressed native libraries in
your APK or Android App Bundle.
According to that same link, you can revert this change by setting extractNativeLibs to true
add this tag on you AndroidManifest.xml file
android:extractNativeLibs="true"
example:
<application
android:extractNativeLibs="true"
... >
</application>
i had the same problem the only thing that help me little is to add abiFilter in build.gradle inside defaultConfig
ndk{
abiFilters "mips","mips64","armeabi","armeabi-v7a","arm64-v8a"
}
I had the same problem, but the provided solution was not working. For those having multidex enabled on your APK your must add the following instead:
android {
packagingOptions {
dex {
useLegacyPackaging true
}
}
}
on your module build.gradle
Source : https://developer.android.com/studio/releases/gradle-plugin#dex_files_uncompressed_in_apks_when_minsdk_28_or_higher

Error when executing crashlyticsGenerateSymbols task with android gradle plugin 3.6+

Where do i report this error? or could anyone help me?
“Directory X specified for property ‘$2’ does not exist” error when executing crashlyticsGenerateSymbols task
with
android gradle plugin 3.6.0
gradle version 5.6.4
fabric gradle plugin 1.31.2
[Error logs]
Some problems were found with the configuration of task ':~~~~~:crashlyticsGenerateSymbolsRelease' (type 'DefaultTask').
Directory '~~~' specified for property '$1' does not exist.
Directory '~~~~' specified for property '$2' does not exist.
Fabric/Firebaser here. This error comes up when the Fabric Gradle plugin is trying to parse your project structure in order to find your stripped and unstripped binaries, and is unable to do so. When it asks for properties $1 and $2 it means it could not find the default paths to the "obj" and "libs" folders that contain your supported ABIs folders with your supported native libraries there.
Using the legacy Fabric Gradle plugin, you can specify these paths under your crashlytics block in the build.gradle, like so:
crashlytics {
enableNdk true
androidNdkOut 'obj'
androidNdkLibsOut 'libs'
}
In the case for builds that are on Android Studio 3.5 or later, you can usually find the paths for these somewhere in the outputted build folders under "merged_native_libs" and "stripped_native_libs."
If you're using the new Firebase Crashlytics SDKs and Gradle plugin, those paths are controlled by "strippedNativeLibsDir" and "unstrippedNativeLibsDir" flags in the firebaseCrashlytics block in your build.gradle.
If you continue running into problems feel free to file a case with Firebase support with more details about your project and what you've tried to configure so far, and you can also still reach out to support#fabric.io.
I got the same issue on my side, and I fixed it by removing ext.enableCrashlytics = false from my app-level build.gradle in
android {
buildTypes {
debug {
// ext.enableCrashlytics = false
}
}
}

Enabling MultiDex Support in Android to achieve 65K+ methods in Eclipse

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

Application too big? Unable to execute dex: Cannot merge new index into a non-jumbo instruction

I am getting the following error when I compile my app:
[2014-05-07 21:48:42 - Dex Loader] Unable to execute dex: Cannot merge new index 65536 into a non-jumbo instruction!
I am at the point that if I declare a new method anywhere in my package, I get this error. If I don't, the app compiles.
I would like to know what exactly (and accurately) does this error mean. My app is big, but I don't think its that big! So:
Does the error mean I have too many methods? public? static? package? members?
Is it related to the methods/members of my root package, or also to the included JAR libraries?
Is there a way to get more debug information about this?
I already know about that "jumbo" enabling flag addressed in the similar questions here in SO, however, I think jumbo mode is not available on the API level I'm targeting (ICS).
Your error is for the amount of strings (methods, members, etc) in a single dex file.
You need to compile you app using jumbo in dex with:
dex.force.jumbo=true
in project.properties
This increment the limit for strings in a dex files. And your project will probably compile.
Also with jumbo set, the is another limit of 64K only for methods in an single dex. If you get this limit in the future , you will need to remove some dependencies.
UPDATE: for build with Gradle:
In Gradle you can enable jumboMode also in the build.gradle file with:
dexOptions {
jumboMode = true
}
Check:
Android Build: Dex Jumbo Mode in Gradle
Also with Gradle you can avoid the 64K limit for methods using multidex build, tutorial here:
https://developer.android.com/tools/building/multidex.html
For gradle build, just add the dexOptions into build.gradle to enable jumbo mode:
android {
dexOptions {
jumboMode = true
}
}
Remember to run "gradle clean" before your new building.
It's related to the number of methods of libraries included in the project. For example if you have tracking in your app, just Google Analytics is ~7000 methods.
In one of my projects using Lombok (2MB of JAR) gave me these problem. Solved getting rid of this library.
It looks like the problem occurs because all the class files from your project and JAR files are packed together before DEXing. This may not be completely true but any way of controlling this in our project has proven to be quite difficult. Even removing stuff that initially caused this problem, cleaning and rebuilding didn't fix the issue for us in a consistent way.
So we took this opportunity to switch our project to Android Studio and managed to solve the problem by turning on ProGuard for debug builds as well. More precisely we only use the shrink phase of the ProGuard's processing chain.
Gradle makes it very easy to turn on ProGuard for debug builds:
buildTypes {
debug {
runProguard true
proguardFile 'proguard-project-debug.txt'
}
}
And here is the debug ProGuard config we use:
-keep class com.your.code.**
# Use -keep to explicitly keep any other classes shrinking would remove
-dontoptimize
-dontobfuscate
-ignorewarnings
This does increase the build time of the project but the good side is that the debugger still works.
The only faster alternative I can think of is that any JAR files are manually stripped of the unused class files. But this is not only difficult to do it is also inconvenient when you want to use a slightly larger part of a library at a later time.
I hope this helps other developers struggling with this issue. And perhaps in the future Google can improve the compiler that does this pruning by default. Our APK DEX file went from 8MB to 2.9MB.
Newer gradle (1.0.0+) versions
In newer Versions of Android studio (1.0+) the bundled Gradle got updated. There were some changes on how the build mechanism works so your project Gradle file can now take advantage of the minifyEnabled and shrinkResources parameters. Current version is 1.1.0.
Keeping up with changes on a fast moving platform like Android takes effort but it is often rewarded with new features, tools and faster build times. So updating Android Studio and (carefully) updating your projects is worth the time you invest.
buildTypes {
debug {
proguardFile 'proguard-project-debug.txt'
minifyEnabled true
shrinkResources true
}
}
Some interesting observations. Same error may appear if you have multi-flavor project. It's confusing. Turned out that I attempted run app with generic command: gradlew installDebug. When I've changed command line to look like this problem is gone. Don't forget to replace Flavor part with your actual one.
gradlew installFlavorDebug

Categories

Resources