Flutter 的 Multidex 问题
Posted
技术标签:
【中文标题】Flutter 的 Multidex 问题【英文标题】:Multidex issue with Flutter 【发布时间】: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 步, 甚至是那一步的遗漏是否是问题所在。
重建步骤:
-
从工具栏中选择
File/New/New Flutter Project
选择“Flutter 应用程序”
包括 Kotlin 和 Swift 支持
检查应用的编译和运行情况
在pubspec.yaml
中添加以下依赖:
dependencies:
flutter_google_place_picker: "^0.0.1"
location: "^1.2.0"
在 Android Studio 中点击 Packages Get
或在项目目录中运行 flutter packages get
修改android/app/build.gradle
,在适当的地方添加以下部分:
dependencies
compile 'com.android.support:multidex:1.0.1'
android
defaultConfig
multiDexEnabled true
从工具栏中选择Run/Run
我尝试过的其他事情
将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'
按照我的每个依赖项的 multidex 步骤进行操作;即修改他们的build.gradle
文件,启用multidex并添加multidex依赖。
build.gradle
文件中将 minSdkVersion 分别修改为 21 和 27,并为它们启用 multidex。
为我的项目启用缩小功能。
将location: "^1.2.0"
替换为geolocation: "^0.2.1"
根本不启用 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!
【问题讨论】:
【参考方案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。
-
启用多索引。
打开[project_folder]/app/build.gradle
并添加以下行。
defaultConfig
...
multiDexEnabled true
和
dependencies
...
implementation 'com.android.support:multidex:1.0.3'
-
启用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);
-
将默认应用程序文件更改为新的。
打开[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 你在CustomApplicationClass
的onCreate()
方法中添加了FacebookSdk.sdkInitialize()
吗?
@YuriMisyac 我正在使用 java 将 FlutterApplication()
更改为 FlutterApplication
解决我的问题,请更新您的代码。它的工作谢谢,
感谢您的精彩回答!但是在 Flutter 1.7 中,我只需要步骤 1 和 2 来让 multi-dex 工作。如果我应用第 3 步和第 4 步,应用程序实际上会崩溃!【参考方案3】:
2021 年及以后的初学者开发者更新:
如果您可以将所需的最低 Android API 级别设置为 21(在撰写本文时,您的应用仍将在 98% 的设备上运行),那么您所要做的就是:
打开位于 [您的项目]\android\app\build.gradle 的“应用程序级 build.gradle 文件”
将 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 文件中
将 minSdkVersion 从 16 增加到 20。
启用 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
默认已启用。
【讨论】:
以上是关于Flutter 的 Multidex 问题的主要内容,如果未能解决你的问题,请参考以下文章
Flutter 在启动时崩溃:在路径 DexPathList 上找不到类 .MainActivity
VM 有 multidex 支持,MultiDex 支持库被禁用。问题
android MultiDex multidex原理原理下遇见的N个深坑