关于android:Flutter的Multidex问题

Multidex issue with Flutter

我在Android Studio中使用Flutter使用gradle编译时遇到以下错误:

1
2
3
4
5
6
7
8
9
10
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;

短版

仅在我添加了足够的依赖项(如预期的那样)时,才会发生这种情况。我已经按照说明(https://developer.android.com/studio/build/multidex.html)启用了multidex并在Android项目build.gradle文件中添加了multidex依赖关系,但是不确定该怎么做Flutter应用程序中的"为multidex配置应用程序"中的第2步,甚至忽略了该步骤是否有问题。

重建步骤:

  • 从工具栏中选择File/New/New Flutter Project
  • 选择" Flutter Application"
  • 包括Kotlin和Swift支持
  • 检查应用编译并运行
  • 将以下内容添加到pubspec.yaml中的依赖项:

    1
    2
    3
    dependencies:
      flutter_google_place_picker:"^0.0.1"
      location:"^1.2.0"
  • 在Android Studio中按Packages Get或在项目目录中运行flutter packages get
  • 修改android/app/build.gradle以在适当的位置添加以下部分:

    1
    2
    3
    4
    5
    6
    7
    8
    dependencies {
      compile 'com.android.support:multidex:1.0.1'
    }
    android {
        defaultConfig {
            multiDexEnabled true
        }
    }

  • 从工具栏中选择Run/Run
  • 我尝试过的其他事情

  • 用以下每个替换build.gradle中的"编译"依赖项:

    1
    2
    3
    compile 'com.android.support:multidex:1.0.3'
    implementation 'com.android.support:multidex:1.0.1'
    implementation 'com.android.support:multidex:1.0.3'
  • 按照我的每个依赖项的multidex步骤进行操作;即修改其build.gradle文件,启用multidex并添加multidex依赖项。

  • 为我的项目及其依赖项将minSdkVersion修改为每个build.gradle文件中的21和27中的每个,并为其启用multidex。
  • 为我的项目启用缩小功能。
  • geolocation:"^0.2.1"替换location:"^1.2.0"
  • 完全不启用multidex(即,跳过重新创建的步骤7)。这将导致以下错误:

    1
    2
    3
    4
    5
    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

  • 颤振医生输出

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    $ 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!

    如果您没有开发Android应用程序的经验,则此信息可能会有所帮助,否则您将找不到任何新内容。

    如何为扑扑项目启用multidex。

  • 启用multidex。
  • 打开project/app/build.gradle并添加以下行。

    1
    2
    3
    4
    5
    defaultConfig {
        ...

        multiDexEnabled true
    }

    1
    2
    3
    4
    5
    dependencies {
        ...

        implementation 'com.android.support:multidex:1.0.3'
    }
  • 启用Jetifier。
  • 打开project/android/app/gradle.properties并添加以下行。

    1
    2
    android.useAndroidX=true
    android.enableJetifier=true

    注:从1.7开始,不再需要以下步骤。

    3)**创建自定义应用程序类。**

    如果您不知道在哪里创建文件,请在MainActivity附近进行操作,例如project/android/app/src/main/kotlin(or java if you didn't enable kotlin)/your/great/pakage/appname/

    kotlin示例:App.kt

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
        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示例:App.java

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
        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);
            }

        }
  • 将默认应用程序文件更改为new。
  • 打开project/android/app/src/main/AndroidManifest.xml

    android:name="io.flutter.app.FlutterApplication"更改为android:name=".App"


    2020年面向初学者的更新:

    如果您可以将最低必需的Android API级别设置为21(可以将您的应用在撰写本文时仍可在94.1%的设备上运行)确定为可以,那么您要做的就是:

  • 打开位于[您的项目] \ android \ app \ build.gradle的"应用程序级别build.gradle文件"

  • 将16(或任何适合您的数字)更改为至少21:

    1
    2
    3
    4
    5
     defaultConfig {
     // ...
     minSdkVersion 16
     // ...
     }
  • ... 至:

    1
    2
    3
    4
    5
    defaultConfig {
        // ...
        minSdkVersion 21
        // ...
    }

    您无需进行任何其他修改即可使Multidex正常工作。

    显然,新Flutter项目的默认minSDK设置为16,因此在pubspec.yaml中添加足够的依赖关系后,许多新开发人员将遇到multidex错误并开始在线搜索,从而可能陷入困惑的信息中,这些信息仅适用于最低水平设置为小于21。


    您的两个软件包似乎在它们的传递依存关系上意见不一致。一个想要11.6。+,另一个想要一些Play-service依赖性的11. +。由于11.6.2和11.8.0都存在,所以最终将导致冲突。

    如果在android/文件夹中运行./gradlew androidDependencies,则会得到依赖关系解析结果的列表,其中包括以下内容:

    1
    2
    3
    4
    5
    6
    7
    +--- :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

    这些11.6.2和11.8.0软件包不能一起使用。要解决此问题,您需要修补依赖项以使其彼此一致,或者将依赖项覆盖添加到android/app/build.gradle文件的顶层并希望达到最佳效果:

    1
    2
    3
    4
    5
    6
    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'
        }
    }


    在android内的应用文件夹中

    1
    2
    3
    4
    5
    defaultConfig {
        ...

        multiDexEnabled true
    }

    还要签出:为使用超过64K方法的应用程序启用multidex


    只需更改app \ build.gradle中的行

    1
    2
    3
    defaultConfig{
    multiDexEnabled true
    }

    不要添加任何依赖
    我首先添加了multidex依赖项,但是程序说找不到它
    然后我将Maven添加到build.gradle中,但未做任何更改

    实际上,您需要将false更改为true
    Android Studio会休息


    在您的应用程序级别的build.gradle文件中

  • 将您的minSdkVersion从16增加到20。

  • 启用multiDex。

    1
    2
    3
    4
    5
    6
    defaultConfig {
         ...

         minSdkVersion 20   //Copy this
         multiDexEnabled true //Copy this  
     }