【问题标题】:Multidex issue with FlutterFlutter 的 Multidex 问题
【发布时间】:2018-09-27 22:07:33
【问题描述】:

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

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;

短版

这仅在我添加足够的依赖项时才会发生,正如预期的那样。我已启用 multidex 并按照说明 (https://developer.android.com/studio/build/multidex.html) 在 Android 项目 build.gradle 文件中添加了 multidex 依赖项,但不确定如何处理 Flutter 应用程序的“为 multidex 配置应用程序”中的第 2 步, 甚至是那一步的遗漏是否是问题所在。

重建步骤:

  1. 从工具栏中选择File/New/New Flutter Project
  2. 选择“Flutter 应用程序”
  3. 包括 Kotlin 和 Swift 支持
  4. 检查应用的编译和运行情况
  5. pubspec.yaml中添加以下依赖:

    dependencies:
      flutter_google_place_picker: "^0.0.1"
      location: "^1.2.0"
    
  6. 在 Android Studio 中点击 Packages Get 或在项目目录中运行 flutter packages get
  7. 修改android/app/build.gradle,在适当的地方添加以下部分:

    dependencies {
      compile 'com.android.support:multidex:1.0.1'
    }
    android {
        defaultConfig {
            multiDexEnabled true
        }
    }
    
  8. 从工具栏中选择Run/Run

我尝试过的其他事情

  1. build.gradle 中的“编译”依赖项替换为以下各项:

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

  3. 在我的项目及其依赖项的每个 build.gradle 文件中将 minSdkVersion 分别修改为 21 和 27,并为它们启用 multidex。
  4. 为我的项目启用缩小功能。
  5. location: "^1.2.0" 替换为geolocation: "^0.2.1"
  6. 根本不启用 multidex(即跳过重新创建的第 7 步)。这会导致以下错误:

    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 -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 flutter android-gradle-plugin


    【解决方案1】:

    您的两个包似乎在传递依赖方面存在分歧。一个想要 11.6.+,另一个想要 11.+ 的一些播放服务依赖项。由于 11.6.2 和 11.8.0 都在那里,这将导致冲突。

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

    +--- :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 文件的顶层添加依赖项覆盖并希望最好:

    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'
        }
    }
    

    【讨论】:

    • 嗨,米克尔。非常感谢您花时间回答。我已经稍微修改了您的答案,以更好地反映对我有用的内容,如果不正确,请告诉我。公平地说,如果我强制解析到可以满足所有插件要求的播放服务版本,应该没有问题吗?
    • 是的,11.8.0 应该向后兼容 11.6.x。
    • 酷。感谢您解释并向我提供工具 (./gradlew androidDependencies),以便将来更好地调查相关问题。
    【解决方案2】:

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


    在大多数情况下,第一步就足够了

    如何为flutter项目启用multidex

    1. 启用多索引。

    打开[project_folder]/app/build.gradle 并添加以下行。

    defaultConfig {
        ...
    
        multiDexEnabled true
    }
    

    dependencies {
        ...
    
        implementation 'com.android.support:multidex:1.0.3'
    }
    
    1. 启用Jetifier

    打开[project_folder]/android/app/gradle.properties 并添加以下行。

    android.useAndroidX=true
    android.enableJetifier=true
    



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




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

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

    kotlin 示例: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 示例: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);
            }
    
        }
    
    1. 将默认应用程序文件更改为新的。

    打开[project_folder]/android/app/src/main/AndroidManifest.xml

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

    【讨论】:

    • 我添加了 extends FlutterApplication 而不是 extends SomeOtherApplication
    • 我在 Java 中实现它,但我也在使用 FacebookLogin 插件,当我实现你的答案时,它说“SDK 尚未初始化,请确保首先调用 FacebookSdk.sdkInitialize()。 "
    • @BarbaricGamester 你在CustomApplicationClassonCreate() 方法中添加了FacebookSdk.sdkInitialize() 吗?
    • @YuriMisyac 我正在使用 java 将 FlutterApplication() { 更改为 FlutterApplication { 解决我的问题,请更新您的代码。它的工作谢谢,
    • 感谢您的精彩回答!但是在 Flutter 1.7 中,我需要步骤 1 和 2 来让 multi-dex 工作。如果我应用第 3 步和第 4 步,应用程序实际上会崩溃!
    【解决方案3】:

    2021 年及以后的初学者开发者更新:

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

    1. 打开位于 [您的项目]\android\app\build.gradle 的“应用程序级 build.gradle 文件”

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

       defaultConfig {
       // ...
       minSdkVersion 16
       // ...
       }
      

    ...到:

    defaultConfig {
        // ...
        minSdkVersion 21
        // ...
    }
    

    无需进行任何其他修改即可让 multidex 正常工作。

    显然,新 Flutter 项目的默认 minSDK 设置仍然是 16,所以在 pubspec.yaml 中添加足够多的依赖项后,许多新开发人员会遇到 multidex 错误并上网搜索,可能会陷入混乱的信息中,这些信息只有适用于最低级别设置为低于 21 的项目。

    【讨论】:

    • 之所以有效,是因为:“如果您的应用仅针对 Android 21 或更高版本 (minSdkVersion),则默认情况下已启用 multidex,您不需要 multidex 支持库。”
    【解决方案4】:

    在你的应用程序文件夹中的 android

    defaultConfig {
        ...
    
        multiDexEnabled true
    }
    

    另请查看:Enable multidex for apps with over 64K methods

    【讨论】:

      【解决方案5】:

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

      1. 将 minSdkVersion 从 16 增加到 20。

      2. 启用 multiDex。

        defaultConfig {
             ...
        
             minSdkVersion 20   //Copy this
             multiDexEnabled true //Copy this  
         }
        

      【讨论】:

        【解决方案6】:

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

        defaultConfig{
        multiDexEnabled true
        }
        

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

        其实你只需要把 false 改成 true 就行了 Android studio 会休息

        【讨论】:

          【解决方案7】:

          如果您通过 USB 安装,请务必在设备请求许可时单击安装按钮,这就是我的解决方案。

          【讨论】:

            【解决方案8】:

            <projectName>\android\app\build.gradle 确保将minSdkVersion 设置为 21

             defaultConfig {
                    ...
                    minSdkVersion 21 // or 20 may be fine
                    ...
                }
            

            无需将multiDexEnabled 设置为true,就好像该应用仅针对Android 21 或更高版本(minSdkVersion)然后multidex 默认已启用。

            【讨论】:

              猜你喜欢
              • 2019-02-13
              • 2020-04-30
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2018-04-21
              • 2019-03-28
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多