一个.dex文件中方法引用的数量不能超过64k API 17。

235

我正在使用SugarORM库构建一个应用程序,但是当我尝试为API 17(未检查其他版本)构建项目时,它会显示构建错误。

    Information:Gradle tasks [:app:assembleDebug]
:app:preBuild UP-TO-DATE
:app:preDebugBuild UP-TO-DATE
:app:checkDebugManifest
:app:preReleaseBuild UP-TO-DATE
:app:prepareComAndroidSupportAnimatedVectorDrawable2330Library UP-TO-DATE
:app:prepareComAndroidSupportAppcompatV72330Library UP-TO-DATE
:app:prepareComAndroidSupportCardviewV72330Library UP-TO-DATE
:app:prepareComAndroidSupportDesign2330Library UP-TO-DATE
:app:prepareComAndroidSupportMediarouterV72300Library UP-TO-DATE
:app:prepareComAndroidSupportRecyclerviewV72330Library UP-TO-DATE
:app:prepareComAndroidSupportSupportV42330Library UP-TO-DATE
:app:prepareComAndroidSupportSupportVectorDrawable2330Library UP-TO-DATE
:app:prepareComAndroidVolleyVolley100Library UP-TO-DATE
:app:prepareComGithubSatyanSugar14Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServices840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesAds840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesAnalytics840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesAppindexing840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesAppinvite840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesAppstate840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesAuth840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesBase840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesBasement840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesCast840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesDrive840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesFitness840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesGames840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesGcm840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesIdentity840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesLocation840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesMaps840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesMeasurement840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesNearby840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesPanorama840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesPlus840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesSafetynet840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesVision840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesWallet840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesWearable840Library UP-TO-DATE
:app:prepareMeDrakeetMaterialdialogLibrary131Library UP-TO-DATE
:app:prepareDebugDependencies
:app:compileDebugAidl UP-TO-DATE
:app:compileDebugRenderscript UP-TO-DATE
:app:generateDebugBuildConfig UP-TO-DATE
:app:generateDebugAssets UP-TO-DATE
:app:mergeDebugAssets UP-TO-DATE
:app:generateDebugResValues UP-TO-DATE
:app:generateDebugResources UP-TO-DATE
:app:mergeDebugResources UP-TO-DATE
:app:processDebugManifest UP-TO-DATE
:app:processDebugResources UP-TO-DATE
:app:generateDebugSources UP-TO-DATE
:app:compileDebugJavaWithJavac
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
:app:compileDebugNdk UP-TO-DATE
:app:compileDebugSources
:app:prePackageMarkerForDebug
:app:transformClassesWithDexForDebug
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:transformClassesWithDexForDebug'.
> com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: java.util.concurrent.ExecutionException: com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command '/Library/Java/JavaVirtualMachines/jdk1.8.0_51.jdk/Contents/Home/bin/java'' finished with non-zero exit value 2
Information:BUILD FAILED
Information:Total time: 21.663 secs
Information:2 errors
Information:0 warnings
Information:See complete output in console

但是当我为Android v5.0或更高版本构建此项目时,它可以正常工作。如果我删除SugarORM的gradle依赖项,则v4.2.2和v5.0的两个设备都可以正常工作。


2
请查看此链接:http://developer.android.com/tools/building/multidex.html。 - Raghunandan
尝试使用Proguard,此链接https://android-arsenal.com/details/1/337指定了在Proguard中使用SugarORM。 - Shaan_B
32
刚升级到API 23,就遇到了这个问题。使用Android开发简直难以提高工作效率,每个SDK都会导致问题出现。每次更新AS也会出问题,错误信息无法使用,AS功能不正常。糟糕透了! - RunLoop
1
@RunLoop 不要失去希望……我发现安卓是迄今为止开发最好的平台……更加灵活和强大……当你开始编码时,一切都会好起来的……每一个错误信息都很有用。但需要理解这些信息。 - Sandeep Rana
2
@Balaj Khan “其中一个或多个答案是值得额外奖励的典范和值得的。回答直截了当且准确。” 我建议选择排名第一的(并被接受的)答案! - Jon Goodwin
显示剩余2条评论
16个回答

519

你的方法过多。DEX文件最多只能有65536个方法

建议使用multidex支持库

只需将以下代码添加到module/build.gradle中:

android {
   
    defaultConfig {
        ...
        
        // Enabling multidex support.
        multiDexEnabled true
    }
    ...
}

dependencies {
  implementation 'androidx.multidex:multidex:2.0.1'  //with androidx libraries
  //implementation 'com.android.support:multidex:1.0.3'  //with support libraries
  
}

或者如果使用 module/build.gradle.kts

android {
    // other properties

    defaultConfig {
        ...

        // Enabling multidex support.
        multiDexEnabled = true
    }
    ...
}

dependencies {
    implementation("androidx.multidex:multidex:2.0.1")  // with androidx libraries
    // implementation("com.android.support:multidex:1.0.3")  // with support libraries
}

同时在你的Manifest文件中,将 multidex 支持库中的 MultiDexApplication 类添加到应用程序元素中。

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.android.multidex.myapplication">
        <application
            ...
            android:name="androidx.multidex.MultiDexApplication">

            <!-- If you are using support libraries use android:name="android.support.multidex.MultiDexApplication" -->

            <!--If you are using your own custom Application class then extend -->
            <!--MultiDexApplication and change above line as-->
            <!--android:name=".YourCustomApplicationClass"> -->

            ...
        </application>
    </manifest>

如果您正在使用自己的Application类,请将父类从Application更改为MultiDexApplication
如果您无法执行此操作,请在Application类中覆盖attachBaseContext方法:

@Override
protected void attachBaseContext(Context newBase) {
    super.attachBaseContext(newBase);
    MultiDex.install(this);
}

另一个解决方案是尝试使用 ProGuard 删除未使用的代码-为您的应用程序配置 ProGuard 设置,以运行ProGuard并确保在发布版本中启用缩小。


1
@Override protected void attachBaseContext(Context newBase) { super.attachBaseContext(newBase); MultiDex.install(this); } 同样可以重写。 - Sandeep Rana
4
如果我没有太多方法,我的应用程序上也没有那么多方法。我相信甚至还不到这个程度。 - Neon Warge
17
我只在build.gradle文件中做了这两部分:"multiDexEnabled true"和compile 'com.android.support:multidex:1.0.0'。我没有改变manifest文件或者按照你提到的覆盖attachBaseContext等其他操作。但是你的解决方案让问题得以解决,感谢。 - Jaime Montoya
2
@NeonWarge 可能是因为你的依赖关系。也许你已经包含了整个 Google Play 服务?请查看此答案以获取详细信息 - mr5
4
我正在使用Flutter,只需在defaultConfig中添加multiDexEnabled true就可以解决我的问题,谢谢。 - Mudasir Habib
显示剩余4条评论

202

在 android/app/build.gradle 中

android {

compileSdkVersion 23

 buildToolsVersion '23.0.0'

    defaultConfig {
        applicationId "com.dkm.example"
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
        multiDexEnabled true
    }

将此内容放入defaultConfig中:

multiDexEnabled true 

它对我有效


3
这只适用于安卓版本为棒棒糖或更高的设备,对吗? - Vic Torious
1
构建成功了,但应用程序启动后崩溃了。 - Vasanth
1
我在我的项目中遇到了同样的问题,但当将multidex设置为true时,问题并没有得到解决,直到我在项目的应用程序模块中启用了multidex。 - FxRi4

26

修改应用级别的build.gradle文件:

android {

compileSdkVersion 23

 buildToolsVersion '23.0.0'

    defaultConfig {
        applicationId "com.dkm.example"
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
        multiDexEnabled true
    }

它对我起作用了。


5
是的,这是一个老问题,但对于API的最新版本,我们只需要使用multiDexEnabled选项,无需更改依赖项或清单文件。 - Hpsaturn
希望我们能把它推到顶部。 - Dror Bar

22

因为在编写我的项目时,自动更新了build.gradle文件中的编译版本,所以我收到了这个错误信息:

android {
    ...
    buildToolsVersion "23.0.2"
    ...
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.4.0'
    compile 'com.android.support:design:23.4.0' }

通过更正版本来解决它:

android {
        ...
        buildToolsVersion "23.0.2"
        ...
    }

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.0.1'
    compile 'com.android.support:design:23.0.1'
}

2
我正在创建一个简单的应用程序,一切都很好,直到我尝试按照Google Map Objects教程操作。突然间,我无法再编译了。这个解决方案已经为我解决了问题。你是怎么想出来的? - maccaroo
5
幸运的是,这种方法可行,因为新的编译库有太多方法(超过了65536),而旧的库没有。所以这只是一个快速修复,迟早你应该像被接受的答案一样添加multidex支持来解决问题。 - Quan Nguyen

19

这是对我有效的方法:

发生这种情况是因为有太多未使用的方法。 大多数这些方法来自于build.gradle中包含的库。

使用minify和shrink resources通过gradle修复此问题,并同时清理代码。

buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        debug {
            minifyEnabled true
            shrinkResources true
        }
    }

16

当你的应用程序引用超过65,536个方法时,你会遇到一个构建错误,指示你的应用已达到Android构建架构的限制。

Android 5.0之前的Multidex支持

在Android 5.0(API级别21)之前的平台版本中,使用Dalvik运行时来执行应用程序代码。默认情况下,Dalvik将应用程序限制为每个APK一个classes.dex字节码文件。为了克服这个限制,您可以将multidex支持库添加到您的项目中:

dependencies {
  implementation 'com.android.support:multidex:1.0.3'
}

Android 5.0及以上版本支持多DEX文件

从Android 5.0(API level 21)开始,系统采用ART运行时,它本身支持从APK文件中加载多个DEX文件。因此,如果您的minSdkVersion为21或更高,则不需要使用multidex支持库。

避免64K限制

  • 使用ProGuard删除未使用的代码-启用代码缩减功能

配置应用程序进行多DEX文件支持

如果您的minSdkVersion设置为21或更高,则只需在模块级别的build.gradle文件中将multiDexEnabled设置为true即可。

android {
defaultConfig {
    ...
    minSdkVersion 21 
    targetSdkVersion 28
    multiDexEnabled true
  }
 ...
}

如果您的minSdkVersion设置为20或更低,则必须使用multidex支持库。

android {
defaultConfig {
    ...
    minSdkVersion 15 
    targetSdkVersion 28
    multiDexEnabled true
   }
   ...
}

dependencies {
  compile 'com.android.support:multidex:1.0.3'
}

覆盖Application类,将其更改为扩展MultiDexApplication(如果可能)如下:

Override the Application class, change it to extend MultiDexApplication (if possible) as follows:

public class MyApplication extends MultiDexApplication { ... }

添加到清单文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp">
    <application
            android:name="MyApplication" >
        ...
    </application>
</manifest>

16

在您仅使用部分Google Play服务API时,加载全部Google Play服务API可能会导致此错误。

根据Google的说法:“在Google Play服务版本6.5以前,您需要将整个API包编译到您的应用程序中。在某些情况下,这样做使得保持您的应用程序(包括框架API、库方法和您自己的代码)中方法数量不超过65,536的限制更加困难。”

从版本6.5开始,您可以选择性地将Google Play服务API编译到您的应用程序中。

例如,当您的应用程序需要play-services-maps、play-services-location时,您只需要在应用程序级别的build.gradle文件中添加这两个API,如下所示:

compile 'com.google.android.gms:play-services-maps:10.2.1'
compile 'com.google.android.gms:play-services-location:10.2.1'

改为:

compile 'com.google.android.gms:play-services:10.2.1'

要获取完整文档和Google Play服务API列表,请单击此处


11

我一直面临着同样的问题,对于multidex支持,您需要记住应用程序的minSdkVersion。如果您使用的是minSdkVersion 21或更高版本,则只需像这样编写multiDexEnabled true

defaultConfig {
    applicationId *******************
    minSdkVersion 21
    targetSdkVersion 24
    versionCode 1
    versionName "1.0"
    multiDexEnabled true
}

对我来说这有效,如果你使用的 minSdkVersion 低于21(低于 lolipop),那么你需要做两件额外简单的事情

1. 首先在你的 build.gradle 中添加以下依赖项

compile 'com.android.support:multidex:1.0.1'

2. 最后,在 manifest 文件中将以下行添加到你的应用程序

android:name="android.support.multidex.MultiDexApplication"

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:name="android.support.multidex.MultiDexApplication"
    android:theme="@style/AppTheme" >
    <activity android:name=".MainActivity" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

那么它也可以在较低版本中工作.. :) 愉快的编码

9

针对React Native或任何Android项目,可添加以下内容以避免多Dex问题:

android {

defaultConfig {
    ...

    // Enabling multidex support.
    multiDexEnabled true
}

}

dependencies {
  implementation 'com.android.support:multidex:1.0.3'  //with support libraries
  //implementation 'androidx.multidex:multidex:2.0.1'  //with androidx libraries

7

针对Unity游戏开发者

如果有人因为这个错误出现在他们的Unity项目中而来到这里,请按照以下步骤进行操作:转到“文件”->“生成设置”->“播放器设置”->“播放器”,然后到“发布设置”下的“构建”选项卡,在其中启用“自定义启动程序Gradle模板”。该文本下将显示一个路径。进入该路径并添加'multiDexEnabled true',像这样:

defaultConfig {
    minSdkVersion **MINSDKVERSION**
    targetSdkVersion **TARGETSDKVERSION**
    applicationId '**APPLICATIONID**'
    ndk {
        abiFilters **ABIFILTERS**
    }
    versionCode **VERSIONCODE**
    versionName '**VERSIONNAME**'
    multiDexEnabled true
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接