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

Posted

技术标签:

【中文标题】.dex 文件中方法引用的数量不能超过 64k API 17【英文标题】:The number of method references in a .dex file cannot exceed 64k API 17 【发布时间】:2016-08-15 13:32:59 【问题描述】:

我正在使用 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 设备。

【问题讨论】:

developer.android.com/tools/building/multidex.html。检查这个 尝试使用 proguard 这个链接android-arsenal.com/details/1/337 指定使用 SugarORM 和 proguard 升级到 api 23 后才得到这个。使用 Android 根本不可能有生产力。每个sdk都会破坏东西。 AS 的每次更新都会破坏一些东西。错误消息无法使用。 AS坏了。垃圾,垃圾,垃圾。 @RunLoop 不要失去希望....我发现 android 是有史以来最好的平台....Moch 灵活而强大....因为您将自己动手编写代码....会好的....每条错误消息都是有用的。但需要理解消息 @Balaj Khan One or more of the answers is exemplary and worthy of an additional bounty.Just to the point and accurate answer. 我建议最高(并已接受)答案!。 【参考方案1】:

你的方法太多了。 dex只能有65536种方法

按照建议,您可以使用multidex support

只需在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
  

同样在您的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,并确保为发布版本启用收缩。

【讨论】:

@Override protected void attachBaseContext(Context newBase) super.attachBaseContext(newBase); MultiDex.install(this); 也覆盖 如果我没有太多方法怎么办。我的应用程序没有那么多方法。我相信它甚至没有达到那个目标。 我只做了这两部分:“multiDexEnabled true”并在我的 build.grandle 文件中编译 'com.android.support:multidex:1.0.0'。我不必更改清单文件中的任何内容,也不必做您提到的有关覆盖 attachBaseContext 等的其他事情。但是您的解决方案为我解决了问题!谢谢。 @NeonWarge 可能是因为你的依赖。也许,您已经包含了整个 Google Play 服务?检查这个answer for details 我正在研究颤振并在 defaultConfig 中仅添加 multiDexEnabled true 对我有用 thnx【参考方案2】:

我将 minSdkVersion 更改为 20,它对我有用。更多详情请查看https://developer.android.com/studio/build/multidex#mdex-gradle

【讨论】:

【参考方案3】:

添加此项以避免 react native 或任何 android 项目的 multidex 问题

安卓

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

【讨论】:

【参考方案4】:

**

对于 Unity 游戏开发者

**

如果有人因为这个错误出现在他们的 Unity 项目中而来到这里,请转到文件->构建设置->播放器设置->播放器。转到发布设置并在构建选项卡下,启用“自定义启动器 Gradle 模板”。该文本下方将显示一条路径。转到路径并像这样添加 multiDexEnabled true :

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

【讨论】:

【参考方案5】:

更改应用级别 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
    

它对我有用。

【讨论】:

是的,这是一个老问题,但对于最新版本的 API,我们只需要 multiDexEnabled 选项,无需依赖项或清单文件更改 希望我们能做到这一点。【参考方案6】:

只是一个旁注,在添加对 multidex 的支持之前 - 确保您没有添加不必要的依赖项。

例如In the official Facebook analytics guide

他们明确指出您应该添加以下依赖项:

implementation 'com.facebook.android:facebook-android-sdk:[4,5)'

这实际上是整个 FacebookSDK - 例如,如果您只需要分析,则需要将其替换为:

implementation 'com.facebook.android:facebook-core:5.+'

Facebook partial SDK options

【讨论】:

完全同意。以我为例,我只需要“使用 facebook 登录”按钮并使用整个 facebook sdk。我已经用facebook-corefacebook-login 替换了它,并且错误消失了。【参考方案7】:

在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 

对我有用

【讨论】:

这仅适用于 Lollipop 或更高版本,不是吗? 它使构建成功,但启动后应用程序崩溃。 你拯救了我的一天! 在我的项目中有同样的问题,但是当将 multidex 设置为 true 时,直到我在项目的模块应用程序中启用 multidex 后问题才能解决【参考方案8】:

当您的应用引用超过 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 及更高版本的 Multidex 支持

Android 5.0(API 级别 21)及更高版本使用称为 ART 的运行时,它本机支持从 APK 文件加载多个 DEX 文件。因此,如果您的 minSdkVersion 为 21 或更高,您确实不需要 multidex 支持库。

避免 64K 限制

使用 ProGuard 删除未使用的代码 - 启用代码收缩

在应用中配置multidex

如果您的 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(如果可能),如下所示:

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>

【讨论】:

【参考方案9】:

仅使用 afew 加载所有 google play services api 时也会出现此错误。

正如 google 所说:“在 6.5 之前的 Google Play 服务版本中,您必须将整个 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 列表,请单击 here

【讨论】:

【参考方案10】:

也可以试试这个:

android
    .
    .
    // to avoid DexIndexOverflowException
    dexOptions 
       jumboMode true
    

希望它可以帮助某人。谢谢

【讨论】:

【参考方案11】:

我也遇到过同样的问题,对于 multidex 支持,您必须牢记应用程序的 minSdkVersion。如果您使用的是 minSdkVersion 21 或更高版本,则只需像这样编写 multiDexEnabled true

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

它适用于我,如果你使用低于 21 的 minSdkVersion(低于 lolipop)那么你必须做两件额外简单的事情

1.首先添加这个依赖

编译'com.android.support:multidex:1.0.1'

在你的 build.gradle 中。

2. 最后和第二个在清单中将下面这一行添加到您的应用程序

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>

Bingo 那么它也可以在较低版本中使用..:) 快乐编码

【讨论】:

【参考方案12】:

您可以在 Android Studio 上启用“即时运行”以获得 multidex 支持。

【讨论】:

【参考方案13】:

对我来说升级 Gradle 工作。在 Android Website 查找更新 然后像这样将它添加到您的 build.gradle (Project) 中

 dependencies 
        classpath 'com.android.tools.build:gradle:2.2.0-alpha4'   
          ....
    

然后将项目与 gradle 文件同步,而且有时可能会因为 java.exe(在我的情况下)而发生这种情况,只需从 Windows 中的任务管理器中强制杀死 java.exe,然后重新运行程序

【讨论】:

【参考方案14】:

这对我有用:

这是因为有太多未使用的方法。 这些方法大部分来自 build.gradle 中包含的库

通过 gradle 使用 minify 和 shrink 资源来解决这个问题,同时清理你的代码。

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

【讨论】:

【参考方案15】:

这样做,它有效:

defaultConfig 
    applicationId "com.example.maps"
    minSdkVersion 15
    targetSdkVersion 24
    versionCode 1
    versionName "1.0"
    multiDexEnabled true

【讨论】:

请解释你的答案。 SO不鼓励仅使用代码的答案。谢谢。【参考方案16】:

我收到此错误消息是因为在我的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'

【讨论】:

我正在创建一个简单的应用程序,它运行良好,直到我尝试按照 Google Map Objects 教程进行操作。突然我无法编译了。这个解决方案为我解决了这个问题。你到底是怎么做到的? 这个方法很幸运,因为新的编译库有太多的方法(超过 65536),而旧的库没有。所以这只是一个快速修复,迟早你应该通过添加 multidex 支持来修复,比如接受的答案。

以上是关于.dex 文件中方法引用的数量不能超过 64k API 17的主要内容,如果未能解决你的问题,请参考以下文章

.dex 文件中的方法引用数超过 64K

DEX 方法超过64K限制和gradle编译OOM问题解决

安卓应用方法数超过64k解决办法:分割Dex

解决Android单个dex文件不能超过65535个方法问题

Android 方法数 65k 限制与 LinearAlloc 限制

Android分包MultiDex源码分析