无法在单个 dex 文件中容纳请求的 类,即使对于之前编译良好的早期提交也是如此
Cannot fit requested classes in a single dex file, even for earlier commits which previously compiled fine
所以我刚刚达到了我的 android 项目的最大方法计数限制,该项目无法构建并显示以下错误消息:
Error: null, Cannot fit requested classes in a single dex file (# methods: 117407 > 65536)
我明白消息的含义,以及如何解决它(运行使用混淆器、启用 multidex 等)。我的问题是我不明白为什么我突然收到这条消息 - 我正在做的是删除一些多余的旧代码,点击构建,现在我收到这条消息。
问题 1:怎么可能我的方法计数(根据错误消息为 117407)突然 大量 超过限制(65536),即使我没有添加任何库依赖项?居然把代码去掉了,突然觉得5万个方法太多了?
现在这就是它变得非常奇怪的地方:我想分析 APK 以找出导致问题的原因,但我当然无法构建它。因此,我没有启用 multidex,而是决定将我的代码恢复到昨天(昨天绝对确实构建良好 - 我的 phone 上有该应用程序来证明这一点!),但我 仍然 得到这个构建错误信息。我不明白这怎么可能。我尝试恢复到几天前,同样的事情(克隆一个新的回购并检查早期的提交)。
所以,问题 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 工作室中使 caches/restart 无效。我真的不想启用 multidex 或必须 运行 在我的调试版本上混淆。
这是完整的build.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
仅这些就让我达到了极限。我仍然不明白为什么这会突然发生 :( 当然,如果我没有添加任何库,这些数字应该不会改变?
我建议使用 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
尽管如此,如果您使用的是混淆器,您可能需要在比较列表之前想出一些方法来应用反向混淆器名称重整。
阅读您的问题后,我只能建议尝试使缓存无效并在之后重新启动并使用此强制刷新您的依赖项。
./gradlew build --refresh-dependencies
查看整个构建 gradle 文件后,您的问题肯定源于您的依赖项!尝试清理它们并尽可能多地删除不使用的内容。您可能非常接近限制,并且任何这些依赖项都可能已使用旧版本缓存。您可以尝试删除整个构建文件夹(并清理您的 gradle 缓存),但我相当确定问题不会消失。
不幸的是,如果需要所有这些依赖项,您将不得不采用您提到的路线,多 dex 或缩小调试版本。 Multi-dex 应该没问题,不应引起任何不可预见的问题,而缩小会减慢构建速度并可能导致 Android Studio 变得不稳定(尤其是即时 run/apply 更改!)
祝你好运,从中得到的一件事是保持你的依赖关系干净和精确,只在绝对需要时添加,如果所有其他方法都失败了,multi-dex 是你的朋友。
作为你的问题,我不得不删除 build
文件夹和 *.iml
文件(Android Studio 项目文件)我不得不重新创建项目,然后构建和然后一切正常。
我遇到了同样的问题,解决方案是在文件 -> 设置 -> 构建、执行、部署 -> 即时 运行 下启用即时 运行,这解决了我的问题。希望对您有所帮助。
简单地将其添加到您的 gradle(模块:应用程序)>> multiDexEnabled true
android {
defaultConfig {
...
minSdkVersion 21
targetSdkVersion 28
multiDexEnabled true
}
...
}
然后重建项目
在菜单中单击 => 构建 > 重建项目。
我试过了。
希望它有帮助,在一些文档中找到它
(忘记了 url :( )
build.gradle 应用
dependencies {...
grdef multidex_version ='2.0.1'
implementation "androidx.multidex:multidex:$multidex_version"
}...
在 bulid.gradle 应用中
implementation 'com.android.support:multidex:2.0.1'
android {
multiDexEnabled true
}
None 他们给你的答案是详尽无遗的。问题出在Multidex
。您必须在应用程序中添加库 gradle:
implementation 'com.android.support:multidex:1.0.3'
之后,你应该在应用程序的默认配置中添加gradle:
multiDexEnabled true
android > 应用 > build.gradle
android {
defaultConfig {
versionCode 1
versionName "1.0"
+ multiDexEnabled true
}
}
添加实现'com.android.support:multidex:1.0.3'
在依赖块中
dependencies {
+ implementation 'com.android.support:multidex:1.0.3'
}
来自 Android 文档:
"If your minSdkVersion is set to 21 or higher, multidex is enabled by default and you do not need the multidex support library."
作为手动启用 multidex 的替代方法,您可以在可能的情况下简单地增加 minSdkVersion。
社区维基
增加这个 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
所以我刚刚达到了我的 android 项目的最大方法计数限制,该项目无法构建并显示以下错误消息:
Error: null, Cannot fit requested classes in a single dex file (# methods: 117407 > 65536)
我明白消息的含义,以及如何解决它(运行使用混淆器、启用 multidex 等)。我的问题是我不明白为什么我突然收到这条消息 - 我正在做的是删除一些多余的旧代码,点击构建,现在我收到这条消息。
问题 1:怎么可能我的方法计数(根据错误消息为 117407)突然 大量 超过限制(65536),即使我没有添加任何库依赖项?居然把代码去掉了,突然觉得5万个方法太多了?
现在这就是它变得非常奇怪的地方:我想分析 APK 以找出导致问题的原因,但我当然无法构建它。因此,我没有启用 multidex,而是决定将我的代码恢复到昨天(昨天绝对确实构建良好 - 我的 phone 上有该应用程序来证明这一点!),但我 仍然 得到这个构建错误信息。我不明白这怎么可能。我尝试恢复到几天前,同样的事情(克隆一个新的回购并检查早期的提交)。
所以,问题 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 工作室中使 caches/restart 无效。我真的不想启用 multidex 或必须 运行 在我的调试版本上混淆。
这是完整的build.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
仅这些就让我达到了极限。我仍然不明白为什么这会突然发生 :( 当然,如果我没有添加任何库,这些数字应该不会改变?
我建议使用 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
尽管如此,如果您使用的是混淆器,您可能需要在比较列表之前想出一些方法来应用反向混淆器名称重整。
阅读您的问题后,我只能建议尝试使缓存无效并在之后重新启动并使用此强制刷新您的依赖项。
./gradlew build --refresh-dependencies
查看整个构建 gradle 文件后,您的问题肯定源于您的依赖项!尝试清理它们并尽可能多地删除不使用的内容。您可能非常接近限制,并且任何这些依赖项都可能已使用旧版本缓存。您可以尝试删除整个构建文件夹(并清理您的 gradle 缓存),但我相当确定问题不会消失。
不幸的是,如果需要所有这些依赖项,您将不得不采用您提到的路线,多 dex 或缩小调试版本。 Multi-dex 应该没问题,不应引起任何不可预见的问题,而缩小会减慢构建速度并可能导致 Android Studio 变得不稳定(尤其是即时 run/apply 更改!)
祝你好运,从中得到的一件事是保持你的依赖关系干净和精确,只在绝对需要时添加,如果所有其他方法都失败了,multi-dex 是你的朋友。
作为你的问题,我不得不删除 build
文件夹和 *.iml
文件(Android Studio 项目文件)我不得不重新创建项目,然后构建和然后一切正常。
我遇到了同样的问题,解决方案是在文件 -> 设置 -> 构建、执行、部署 -> 即时 运行 下启用即时 运行,这解决了我的问题。希望对您有所帮助。
简单地将其添加到您的 gradle(模块:应用程序)>> multiDexEnabled true
android {
defaultConfig {
...
minSdkVersion 21
targetSdkVersion 28
multiDexEnabled true
}
...
}
然后重建项目 在菜单中单击 => 构建 > 重建项目。
我试过了。 希望它有帮助,在一些文档中找到它 (忘记了 url :( )
build.gradle 应用
dependencies {...
grdef multidex_version ='2.0.1'
implementation "androidx.multidex:multidex:$multidex_version"
}...
在 bulid.gradle 应用中
implementation 'com.android.support:multidex:2.0.1'
android {
multiDexEnabled true
}
None 他们给你的答案是详尽无遗的。问题出在Multidex
。您必须在应用程序中添加库 gradle:
implementation 'com.android.support:multidex:1.0.3'
之后,你应该在应用程序的默认配置中添加gradle:
multiDexEnabled true
android > 应用 > build.gradle
android { defaultConfig { versionCode 1 versionName "1.0" + multiDexEnabled true } }
添加实现'com.android.support:multidex:1.0.3' 在依赖块中
dependencies { + implementation 'com.android.support:multidex:1.0.3' }
来自 Android 文档:
"If your minSdkVersion is set to 21 or higher, multidex is enabled by default and you do not need the multidex support library."
作为手动启用 multidex 的替代方法,您可以在可能的情况下简单地增加 minSdkVersion。
社区维基 增加这个 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