Why does a Flutter project exceed 64K method reference in its .dex file?
I am wondering what the cause of this could be:
In a rather small Flutter project I use 13 plugins. Without Multidex, the Android build fails because it vastly exceeds the method reference limit.
Is there any trick (e.g. Gradle related) that would allow to shrink the method reference count because I think that such a project should not exceed the limit?
(if you want further information on why I think that this is odd, please take a look at older revisions of this question)
I had the same problem and the fix for me was increasing the minSdkVersion in the app/build.bradle like this
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
minSdkVersion 21 // change this to 21
targetSdkVersion 28
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
If you are using minSdkVersion less than 21, you can do the following to enable multidex.
In your app level build.gradle change as follows:
Add multiDexEnabled true to defaultConfig
defaultConfig {
minSdkVersion 15
targetSdkVersion 28
...
multiDexEnabled true
}
Add multidex dependency
dependencies {
...
implementation 'androidx.multidex:multidex:2.0.1'
}
You can refer this for more information.
in your android/app/build file increase the minsdkversion from 16 to 21 under defautConfig.
Some have even increased it to 28 but it worked for me at 21.
Here is the link to the issue on git
Edit: multiDexEnabled: true also works for some under the same defautConfig.
in the build.gradle under the defaultConfig add the multiDexEnabled true
minSdkVersion 16
targetSdkVersion 30
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
multiDexEnabled true
}
Use ProGuard to eliminate unused classes at compile time. This will reduce your method count by a considerable amount.
You will need to adjust the ProGuard rules to work with Flutter like the Flutter documentation explains here.
I successfully migrated the app to androidx using the below link and the second step:
1) Flutter Projects & Android X Migration Issues
2) In your android/app/build file increase the minsdkversion from 16 to 21 under defaultConfig. Some have even increased it to 28 but it worked for me at 21.
There is another solution without multidex or increasing min SDK. But it's need R8, just enable minify on App level build.gradle
buildTypes {
release {
minifyEnabled true
}
debug {
minifyEnabled true
}
}
from github comment
or to run debug without minify github comment
buildTypes {
release {
minifyEnabled true
}
debug {
defaultConfig.minSdkVersion 21
}
}
Option 1: use the multidex Library.
Option 2: increase your min SDK to 21 or higher
Detailed explanation on using Multidex Library:
Versions of the platform prior to Android 5.0 (API level 21) use the Dalvik runtime for executing app code. By default, Dalvik limits apps to single classes.dex bytecode file per APK. In order to get around this limitation, you can add the multidex library to the module-level build.gradle file:
Steps to fixing it: set multiDex enabled to true
defaultConfig {
minSdkVersion 15
targetSdkVersion 28
...
multiDexEnabled true
}
Add multidex dependency:
dependencies {
implementation "androidx.multidex:multidex:2.0.1" }
Detailed explanation on why increasing your min SDK to 21 in your android/app/build.gradle works is:
Android 5.0 (API level 21) and higher uses a runtime called ART which natively supports loading multiple DEX files from APK files. ART performs pre-compilation at app install time which scans for classesN.dex files and compiles them into a single .oat file for execution by the Android device. Therefore if you have your min SDK set to 21 or higher, you do not need the multidex Library.
Here is a more detailed write up about the issue:
https://developer.android.com/studio/build/multidex
Related
When developing for Instant Apps the use of Configuration APKs (https://developer.android.com/topic/instant-apps/guides/config-splits.html) offers useful option for cutting down on APK size. However it looks like they are only supported when using mindSdk of 21 or later. For example, you get following error if you try to use this capability for lower sdk versions.
MinSdkVersion 17 is too low (<21) to support pure splits, reverting to full APKs
Is there way to have base module for example use pure split functionality while still having installed app target pre lollipop devices?
Since the minSdkVersion flag will toggle quite a few checks, this change is not done automatically for you.
I'd recommend introducing a product flavor for both the installed and instant module with different minSdkVersions, like this:
// :feature/base/build.gradle
flavorDimensions 'delivery'
productFlavors {
instant {
dimension 'delivery'
minSdkVersion rootProject.minSdkInstant
}
installed {
dimension 'delivery'
}
}
This will have to be done similarly in other modules that depend on the feature module with API level < 21.
Instant apps are only supported in API 21+ devices (link), older devices will only support full apk.
The better approach is to define different minSdk based on your module, like:
You can take a look at Google's analytics sample on GitHub
Project's gradle
ext {
buildTools = '26.0.2'
compileSdk = 26
minSdk = 15
minSdkInstant = 21
versionCode = 1
versionName = '1.0'
supportLib = '26.1.0'
firebaseVer = '10.2.4'
instantAppsVer = '1.0.0'
}
Base gradle
android {
compileSdkVersion rootProject.compileSdk
buildToolsVersion rootProject.buildTools
baseFeature true
defaultConfig {
minSdkVersion rootProject.minSdk
targetSdkVersion rootProject.compileSdk
versionCode rootProject.versionCode
versionName rootProject.versionName
}
buildTypes {
release {}
}
}
Installed gradle
defaultConfig {
applicationId "com.example.android.instant.analytics"
minSdkVersion rootProject.minSdk
targetSdkVersion rootProject.compileSdk
versionCode rootProject.versionCode
versionName rootProject.versionName
}
Instant gradle
android {
defaultConfig {
minSdkVersion rootProject.minSdkInstant
}
}
You can specify a different lower minSdkVersion for your application module if you use tools:overrideLibrary Please see How do I use tools:overrideLibrary in a build.gradle file?
This is how I did it:
app/build.gradle
android {
defaultConfig {
minSdkVersion 17
}
}
app’s manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.package.app" xmlns:tools="http://schemas.android.com/tools" >
<uses-sdk tools:overrideLibrary="com.package,com.package.feature"/>
</manifest>
You will need to add all the package names where you wish to override their minSdkVersion. You will know which ones to add by looking at the error:
Manifest merger failed ...
AndroidManifest.xml as the library might be using APIs not available
in 17 Suggestion: use a compatible library with a minSdk of at most
17,
or increase this project's minSdk version to at least 21,
or use tools:overrideLibrary="com.package.feature" to force usage (may lead to runtime failures)
base and feature/build.gradle
android {
defaultConfig {
minSdkVersion 21
}
}
Test it by building the installed/instant APKs, then analyzing then for the minSdkVersion value. The installed should be at 17, and your base/feature APKs will still be on 21.
Hello I get the 2 errors when trying to generate a signed APK. Although when I build the project it has O errors.
I have gone to the links tried to make the modifications but it comes up with more errors
Error:The number of method references in a .dex file cannot exceed 64K.
Learn how to resolve this issue at https://developer.android.com/tools/building/multidex.html
Error:Execution failed for task ':app:transformClassesWithDexForRelease'.
com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: java.util.concurrent.ExecutionException: java.lang.UnsupportedOperationException
Configure your app for multidex
Setting up your app project to use a multidex configuration requires that you make the following modifications to your app project, depending on the minimum Android version your app supports.
If your minSdkVersion is set to 21 or higher, all you need to do is set multiDexEnabled to true in your module-level build.gradle file, as shown here:
android {
defaultConfig {
...
minSdkVersion 21
targetSdkVersion 25
multiDexEnabled true
}
...
}
However, if your minSdkVersion is set to 20 or lower, then you must use the multidex support library as follows:
Modify the module-level build.gradle file to enable multidex and add the multidex library as a dependency, as shown here:
android {
defaultConfig {
...
minSdkVersion 15
targetSdkVersion 25
multiDexEnabled true
}
...
}
dependencies {
compile 'com.android.support:multidex:1.0.1'
}
This is the point I though I should put it in my code. I looked around and tried a couple more locations although I keep getting errors.
android {
compileSdkVersion 25
buildToolsVersion "23.0.3"
defaultConfig {
applicationId "com.adventure.game"
minSdkVersion 10
targetSdkVersion 25
versionName '1'
versionNameSuffix '1.0'
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
productFlavors {
}
}
If anyone can help, that would be great.
Thanks in advance.
I had the 64k error in one of my apps, and the solution was not to use the multidex.
My problem was that I was importing all the google services with this line in my dependencies: compile 'com.google.android.gms:play-services:10.0.1'. Google brought 64k classes to my app, so I removed this compile line and imported only the services I needed (the location service).
You can find the complete list here.
And this worked for me.
I hope this will help you.
This question already has answers here:
Android Multidex RuntimeException
(2 answers)
Closed 6 years ago.
My app is running fine on Lollipop devices. But when I try to run the app on below Lollipop devices it is giving error everytime.
the error is given below:
Error:The number of method references in a .dex file cannot exceed 64K.
:app:transformClassesWithDexForDebug FAILED
Error:Execution failed for task ':app:transformClassesWithDexForDebug'.
My gradle file is below:
defaultConfig {
applicationId "com.ielts.touchstone.touchstone"
minSdkVersion 15
targetSdkVersion 23
versionCode 1
versionName "1.0.4"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
Try adding multiDexEnabled true to your app build.gradle file.
defaultConfig {
multiDexEnabled true
}
Also , Clean Your Project first.
Your app has more than 64K methods which are not supported by default prior to android 5.0, hence the exception. To support more than 64K methods below 5.0 add multidex support to your app.
Add the following code in your app module's gradle file
android {
.
.
.
defaultConfig {
...
...
// Enabling multidex support.
multiDexEnabled true
}
...
}
dependencies {
compile 'com.android.support:multidex:1.0.0'
}
and in your manifest add the MultiDexApplication class from the multidex support library to the application element.
<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>
More details can be found here
Your application is crossing 64K method limit. Upto API 19, android system uses dalvik processors which is having limit of 64k methods. But from API 21, android system uses Android Runtimes, so that you have to add multiDexEnabled true if you are building your app for API 21 n above. It will Configure Apps with Over 64K Methods.
Check this -
https://developer.android.com/studio/build/multidex.html
Hope it will help :)
I read that my app will be able to run on the minimum SDK version, 16 in this case:
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
applicationId "com.github.dht.screenger"
minSdkVersion 16
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
...
So what will happen with level 23 dependencies when running on an API 16 device?
Dependencies
compile 'com.android.support:appcompat-v7:23.2.0'
compile 'com.android.support:recyclerview-v7:23.2.0'
....
IT mainly depends on the feature and have you used support library or not, cause in case you have used a feature from the support library that's backward compatible then the library takes care of it else the native behavior kicks in,
Lets take the most common scenario, The status bar
IN API level 16 there is no status bar color tinting but a black status bar is shown but from API 21 on-wards it's there so here as we can see the native behavior of that particular version kicks-in
now lets see the com.android.support:recyclerview-v7:23.2.0
As you can see the v7 specifies that the library is backward compatible till version API version 7( ECLAIR_MR1) so the support library does that for you.
The final case using methods available only in that particular version
of SDK
When this happens the compiler throws an error saying you cant use this since the min supported version does not have this methods.
In my app build.gradle
compileSdkVersion 23
minSdkVersion 16
targetSdkVersion 23
compile 'com.android.support:appcompat-v7:23.0.1'
compile 'com.android.support:recyclerview-v7:23.0.1'
since API 24 cameout, I changed the targetSdkVersion to 24, but then the last 2 dependencies show the squiggly-red-underline (not happy with using lower version than targetSdkVersion), I could not find dependencies libraries that support API 24.
According to my understanding of Jim Mixon post, I did not expect this problem. How can it be fixed?
in my Android SDK Manager window where Packages are listed, under Tools, I have the first line "name:Android SDK Tools, API:"BLANK", Rev.:24.4, Status:Installed). is not that a SDK 24 being installed?
As mentioned by CommonsWare, the API or SDK version 24 is not available yet.
If you want to change your build version (<= 23) and two dependencies, you can follow these steps:
1- click and right-click your project or module. Choose 'Open Module Setting' option.
2- In the list that can be viewed menu, you can your build version and just below the related API.
3- In the tab 'Dependencies' you can click the + button and add a dependency. choose option '1 Library Dependency'.
If your build version is < 23 you can manually add to your .gradle file
example:
android {
compileSdkVersion 19
buildToolsVersion '19.1.0'
defaultConfig {
minSdkVersion 10
targetSdkVersion 19
versionCode 65
versionName "2.4.1"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
}
dependencies {
compile 'com.android.support:support-v4:19.1.0'
}
p.s.Sorry for English. It's not my native language
I hope it can help you =]
since API 24 cameout
There is no API 24 at the present time.
How can it be fixed?
Do not refer to API levels that do not presently exist.