无法将请求的类放入单个dex文件中,即使对于先前已编译良好的提交也是如此

时间:2019-02-27 18:08:10

标签: android android-studio android-gradle dex

所以我刚刚达到了我的android项目的最大方法计数限制,该项目无法构建并显示以下错误消息:

  

错误:空,无法将请求的类放入单个dex文件中(#方法:117407> 65536)

我了解该消息的含义以及如何解决(运行proguard,启用multidex等)。我的问题是我不明白为什么突然收到此消息-我正在做的是删除一些多余的旧代码,点击生成,现在我收到此消息。

问题1:即使我未添加任何库依赖关系,我的方法计数(根据错误消息为117407)怎么可能突然大量超过限制(65536)?我实际上删除了代码,突然间我喜欢5万种方法?

现在这真是很奇怪:我想分析APK以找出导致问题的原因,但是我当然不能构建它。因此,除了启用multidex之外,我决定将代码还原为昨天(绝对可以在昨天完全正常构建-我的手机上已经安装了该应用程序以证明这一点!),但是我 still 仍然收到此构建错误消息。我不知道这怎么可能。我尝试恢复到几天前的同一件事(克隆一个新的repo并签出一个较早的提交)。

因此,问题2:对于昨天刚构建好的没有错误的完全相同的代码,我如何得到此构建错误?

我唯一能想到的是,我用作依赖项的库的大小突然增加了-但是我在gradle构建中声明了所有版本的特定版本,例如:

// RxJava
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
implementation 'io.reactivex.rxjava2:rxjava:2.2.4'

// Retrofit
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'

那么,我的依赖关系肯定不会改变吗?

任何能解决此问题的想法都将受到赞赏。我试过清理我的项目,并使android studio中的缓存无效/重启。我真的不想启用multidex,也不必在调试版本上运行proguard。

这是完整的版本。gradle:

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'

android {
    compileSdkVersion 28
    defaultConfig {
    applicationId "XXXXXXXXX"
    minSdkVersion 19
    targetSdkVersion 28
    versionCode 1
    versionName "0.1"
    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    vectorDrawables.useSupportLibrary = true  // see https://developer.android.com/studio/write/vector-asset-studio#sloption
}
buildTypes {
    release {
        minifyEnabled false
        // Do code shrinking!
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}
}

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])

// Core stuff
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:recyclerview-v7:28.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'android.arch.lifecycle:extensions:1.1.1'
implementation 'com.android.support:design:28.0.0'
implementation 'com.android.support:support-vector-drawable:28.0.0'
implementation 'com.google.android.gms:play-services-wearable:16.0.1'

// Dagger
implementation 'com.google.dagger:dagger:2.21'
kapt 'com.google.dagger:dagger-compiler:2.21'
// Dagger for Android
implementation 'com.google.dagger:dagger-android:2.21'
implementation 'com.google.dagger:dagger-android-support:2.21' // if you use the support libraries
kapt 'com.google.dagger:dagger-android-processor:2.21'

// Constraint layout
implementation 'com.android.support.constraint:constraint-layout:1.1.3'

// Associated WearOS project
wearApp project(':wear')

// Common library project
implementation project(':common')

// These were added to resolve gradle error on the 'com.android.support:appcompat-v7:28.0.0' implementation:
// All com.android.support libraries must use the exact same version specification (mixing versions can lead to
// runtime crashes). Found versions 28.0.0, 26.1.0. Examples include com.android.support:animated-vector-drawable:28.0.0
// and com.android.support:support-media-compat:26.1.0
// This seems to be related to linking the wear project. If the wear project was not linked, the error went away.
implementation 'com.android.support:support-media-compat:28.0.0'
implementation 'com.android.support:support-v4:28.0.0'

// RxJava
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
implementation 'io.reactivex.rxjava2:rxjava:2.2.4'

// Retrofit
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
// Retrofit RxJava
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.5.0'
// Retrofit logging:
implementation 'com.squareup.okhttp3:logging-interceptor:3.12.1'

// Room
def room_version = "1.1.1"
implementation "android.arch.persistence.room:runtime:$room_version"
implementation "android.arch.persistence.room:common:$room_version"
implementation "android.arch.persistence.room:rxjava2:$room_version"
kapt "android.arch.persistence.room:compiler:$room_version"

// For modern time handling (java.time requires API 26 or higher)
implementation 'com.jakewharton.threetenabp:threetenabp:1.1.1'

// Graphing
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0-alpha'

// Dropbox
implementation 'com.dropbox.core:dropbox-core-sdk:3.0.11'

// OpenCSV
implementation 'com.opencsv:opencsv:4.5'

}

编辑

因此,在启用multidex后,当我使用Android Studio分析APK时,以下TLD下会显示一些严重的依赖关系(不确定我是否应该查看定义或引用的方法编号?)

  • com.dropbox:26000个定义方法,34000个引用方法
  • com.android(主要支持库):已定义18700,已引用24600
  • org.apache(常见,日志等):已定义15000,已引用15700

仅凭这些,我就达到了极限。我仍然不明白为什么这突然发生了:((当然,如果我没有添加任何库,这些数字应该不会改变吗?

12 个答案:

答案 0 :(得分:3)

他们给您的答案都没有详尽无遗。问题出在Multidex上。您必须在应用程序gradle中添加库:

implementation 'com.android.support:multidex:1.0.3'

之后,您应该添加应用gradle的defaultConfig:

multiDexEnabled true

答案 1 :(得分:2)

查看完整个构建gradle文件后,您的问题肯定是由您的依赖引起的!尝试清理它们,并清除不使用的东西。您很有可能已接近极限,并且其中的任何依赖项都可能已使用旧版本进行了缓存。您可以尝试删除整个构建文件夹(并清理gradle缓存),但是我敢肯定这个问题不会消失。

不幸的是,如果所有这些依赖项都是必需的,则您必须按照您提到的路线进行操作,无论是multi-dex还是最小化调试版本。 Multi-dex应该可以,并且不会造成任何不可预见的问题,而缩小会导致构建速度变慢,并可能导致Android Studio变得不稳定(尤其是即时运行/应用更改!)

祝您好运,要采取的一项措施是保持您的依赖项整洁准确,仅在绝对需要时添加,否则,如果所有其他方法都失败,multi-dex是您的朋友。

答案 2 :(得分:1)

简单地将其添加到gradle(模块:应用程序)>> multiDexEnabled true

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

然后重建项目 在菜单中,单击=>生成>重建项目。

答案 3 :(得分:0)

我建议使用multidex构建应用程序,然后从新apk的多个dex文件中提取方法ID,并从旧的单dex apk提取方法id并比较两个列表。

>

大概是这样的:

baksmali list dex new.apk
baksmali list method new.apk/classes.dex > new.list
baksmali list method new.apk/classes2.dex >> new.list
sort new.list > new.sorted.list

baksmali list method old.apk > old.list
diff new.sorted.list old.list

尽管,如果您使用的是proguard,则在比较列表之前,可能需要找出某种方法来应用反向的proguard名称修饰。

答案 4 :(得分:0)

在阅读您的问题之后,我只能建议尝试使缓存无效并在之后重新启动,并使用此命令强制刷新您的依赖项。

./gradlew build --refresh-dependencies

答案 5 :(得分:0)

作为您的问题,我必须删除build文件夹和*.iml文件(Android Studio项目文件),并且必须重新创建项目,然后进行构建,然后一切都可以正常工作。

答案 6 :(得分:0)

我遇到了同样的问题,解决方案是在文件->设置->构建,执行,部署->即时运行下启用即时运行,这解决了我的问题。希望对您有所帮助。

答案 7 :(得分:0)

我尝试过了。  希望对您有所帮助,可以在一些文档中找到它 (忘记了网址:()

build.gradle应用

dependencies {...
grdef multidex_version ='2.0.1'

implementation "androidx.multidex:multidex:$multidex_version"
}...

答案 8 :(得分:0)

在bulid.gradle应用程序中

implementation 'com.android.support:multidex:2.0.1'

android {
    multiDexEnabled true

}

答案 9 :(得分:0)

android> app> build.gradle

  1. android {
    
        defaultConfig {
            versionCode 1
            versionName "1.0"
          +  multiDexEnabled true
        }
    }
    
  2. 添加实现'com.android.support:multidex:1.0.3' 在依赖项块中

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

答案 10 :(得分:0)

来自Android文档:

“如果您的minSdkVersion设置为21或更高,则默认情况下启用multidex,并且您不需要multidex支持库。”

作为手动启用multidex的替代方法,如果可能的话,您可以简单地增加minSdkVersion。

答案 11 :(得分:0)

社区Wiki 只需增加此minSdkVersion和targetSdkVersion即可:

旧:

defaultConfig {minSdkVersion 19 targetSdkVersion 28 versionCode flutterVersionCode.toInteger()versionName flutterVersionName}

新功能:

defaultConfig {minSdkVersion 21 targetSdkVersion 29 versionCode flutterVersionCode.toInteger()versionName flutterVersionName}

这也是compileSdkVersion:

旧:

android {compileSdkVersion 28

新功能:

android {compileSdkVersion 29