Multidex issue with Flutter
I'm getting the following error compiling with gradle using Flutter in Android Studio:
Dex: Error converting bytecode to dex:
Cause: com.android.dex.DexException: Multiple dex files define Lcom/google/android/gms/internal/zzcew;
UNEXPECTED TOP-LEVEL EXCEPTION:
com.android.dex.DexException: Multiple dex files define Lcom/google/android/gms/internal/zzcew;
[... stacktrace omitted for brevity ...]
* What went wrong:
Execution failed for task ':app:transformDexArchiveWithDexMergerForDebug'.
> com.android.build.api.transform.TransformException: com.android.dex.DexException: Multiple dex files define Lcom/google/android/gms/internal/zzcew;
The short version
This only occurs if I add enough dependencies, as might be expected. I've enabled multidex and added the multidex dependency in the Android project build.gradle
file as per instructions (https://developer.android.com/studio/build/multidex.html), but wasn't sure what to do about step 2 in "Configure your app for multidex" for a Flutter App, or even whether the omission of that step was the problem.
Steps to recreate:
- Select
File/New/New Flutter Project
from the toolbar - Select "Flutter Application"
- Include Kotlin & Swift support
- Check the app compiles and runs
-
Add the following to dependencies in
pubspec.yaml
:dependencies: flutter_google_place_picker: "^0.0.1" location: "^1.2.0"
- Hit
Packages Get
in Android Studio or runflutter packages get
in the project directory -
Modify
android/app/build.gradle
to add the following sections in the appropriate places:dependencies { compile 'com.android.support:multidex:1.0.1' } android { defaultConfig { multiDexEnabled true } }
- Select
Run/Run
from the toolbar
Other things I've tried
-
Replacing the "compile" dependency in
build.gradle
with each of the following:compile 'com.android.support:multidex:1.0.3' implementation 'com.android.support:multidex:1.0.1' implementation 'com.android.support:multidex:1.0.3'
Following the multidex steps for each of my dependencies; i.e. modifying their
build.gradle
files, enabling multidex and adding the multidex dependency.- Modifying minSdkVersion to each of 21 and 27 in each of the
build.gradle
files for my project and its dependencies, and enabling multidex for them. - Enabling minifying for my project.
- Replacing
location: "^1.2.0"
withgeolocation: "^0.2.1"
-
Not enabling multidex at all (i.e. skipping step 7 of recreating). This results in the following error:
FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ':app:transformDexArchiveWithExternalLibsDexMergerForDebug'. > java.lang.RuntimeException: java.lang.RuntimeException: com.android.builder.dexing.DexArchiveMergerException: Unable to merge dex
Flutter doctor output
$ flutter doctor -v
[√] Flutter (Channel beta, v0.2.8, on Microsoft Windows [Version 10.0.16299.371], locale en-GB)
• Flutter version 0.2.8 at D:\flutter
• Framework revision b397406561 (2 weeks ago), 2018-04-02 13:53:20 -0700
• Engine revision c903c217a1
• Dart version 2.0.0-dev.43.0.flutter-52afcba357
[√] Android toolchain - develop for Android devices (Android SDK 27.0.3)
• Android SDK at C:\Users\Dave\AppData\Local\Android\sdk
• Android NDK location not configured (optional; useful for native profiling support)
• Platform android-27, build-tools 27.0.3
• Java binary at: D:\AndroidDev\jre\bin\java
• Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1024-b02)
• All Android licenses accepted.
[√] Android Studio (version 3.1)
• Android Studio at D:\AndroidDev
• Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1024-b02)
[√] Connected devices (1 available)
• Android SDK built for x86 64 • emulator-5554 • android-x64 • Android 5.1.1 (API 22) (emulator)
• No issues found!
Solution 1:
If you don't have experience with developing android application this information can be helpful otherwise you won't find anything new.
In most cases, enough will do the first step
How to enable multidex for flutter project.
- Enable multidex.
Open [project_folder]/app/build.gradle
and add following lines.
defaultConfig {
...
multiDexEnabled true
}
and
dependencies {
...
implementation 'com.android.support:multidex:1.0.3'
}
- Enable Jetifier.
Open [project_folder]/android/app/gradle.properties
and add following lines.
android.useAndroidX=true
android.enableJetifier=true
NOTE: As of flutter 1.7, the below steps are no longer necessary.
3) **Create custom application class.**
If you don't know where to create the file do it near MainActivity
for example [project_folder]/android/app/src/main/kotlin(or java if you didn't enable kotlin)/your/great/pakage/appname/
kotlin example: App.kt
package your.great.pakage.appname
import io.flutter.app.FlutterApplication
import android.content.Context
import androidx.multidex.MultiDex
class App : FlutterApplication() {
override fun attachBaseContext(base: Context) {
super.attachBaseContext(base)
MultiDex.install(this)
}
}
java example: App.java
package your.great.pakage.appname;
import io.flutter.app.FlutterApplication;
import android.content.Context;
import androidx.multidex.MultiDex;
public class App extends FlutterApplication {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
}
- Change the default application file to new.
Open [project_folder]/android/app/src/main/AndroidManifest.xml
Change android:name="io.flutter.app.FlutterApplication"
to android:name=".App"
Solution 2:
Update for beginner devs in 2021 and beyond:
If you're OK with setting the minimum required Android API level as high as 21 (your app will still run on 98% of devices as of this writing), then all you have to do is this:
-
Open your "app level build.gradle file" which exists at [your project]\android\app\build.gradle
-
Change the 16 (or whatever number it is for you) to at least a 21:
defaultConfig { // ... minSdkVersion 16 // ... }
... to:
defaultConfig {
// ...
minSdkVersion 21
// ...
}
You don't have to make ANY other modifications in order for multidex to work correctly.
Apparently, the default minSDK setting for new Flutter projects is still 16, so after adding enough dependencies in pubspec.yaml, many new developers will run into the multidex error and go searching online, potentially getting bogged down in confusing information which only applies to projects with a minimum level set to less than 21.
Solution 3:
Your two packages seem to disagree on their transitive dependencies. One wants 11.6.+, the other wants 11.+ of some play-services dependencies. Since both 11.6.2 and 11.8.0 are out there, this is going to end up with a conflict.
If you run ./gradlew androidDependencies
in your android/
folder, you get a listing of the result of dependency resolution, containing, among others, the following:
+--- :flutter_google_place_picker (variant: release)
+--- com.google.android.gms:play-services-location:11.8.0@aar
+--- com.google.android.gms:play-services-places:11.6.2@aar
+--- com.google.android.gms:play-services-maps:11.6.2@aar
+--- com.google.android.gms:play-services-base:11.8.0@aar
+--- com.google.android.gms:play-services-tasks:11.8.0@aar
+--- com.google.android.gms:play-services-basement:11.8.0@aar
These 11.6.2 and 11.8.0 packages are not going to work together. To resolve this, you need to patch your dependencies to be consistent with each other, or add a dependency override to the top level of your android/app/build.gradle
file and hope for the best:
configurations.all {
resolutionStrategy {
force 'com.google.android.gms:play-services-places:11.8.0'
force 'com.google.android.gms:play-services-location:11.8.0'
}
}
Solution 4:
in your app folder inside android
defaultConfig {
...
multiDexEnabled true
}
Also check out: Enable multidex for apps with over 64K methods