无法将请求的类放在单个dex文件中,即使对于之前编译正常的早期提交也是如此
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无法将请求的类放在单个dex文件中,即使对于之前编译正常的早期提交也是如此相关的知识,希望对你有一定的参考价值。
所以我刚刚达到我的android项目的最大方法计数限制,无法使用以下错误消息构建:
错误:null,无法在单个dex文件中容纳请求的类(#methods:117407> 65536)
我理解消息的含义,以及如何解决它(运行proguard,启用multidex等)。我的问题是,我不明白为什么我突然收到这条消息 - 我正在做的是删除一些旧的代码,这些代码是冗余的,命中构建,现在我得到了这条消息。
问题1:即使我没有添加任何库依赖项,我的方法计数(117407根据错误消息)突然大大超过限制(65536)怎么可能?我实际上删除了代码,突然间我有5万个方法太多了?
现在这就变得非常奇怪:我想分析APK以找出造成问题的原因,但当然我无法构建它。因此,我没有启用multidex,而是决定将我的代码恢复到昨天(这绝对确实在昨天构建得很好 - 我在手机上有应用程序来证明它!),但我仍然收到此构建错误消息。我不明白这是怎么可能的。几天前我尝试恢复,同样的事情(克隆一个新的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。
这是完整的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(commons,log etc):15000定义,15700引用
仅这些就把我带到了极限。我仍然不明白为什么突然发生这种情况:(当然如果我没有添加任何库,这些数字应该不会改变?
查看完整的构建gradle文件后,您的问题肯定源于您的依赖项!尝试清理它们并尽可能多地删除你不使用的东西。您可能非常接近限制,并且可能已使用旧版本缓存了任何这些依赖项。您可以尝试删除整个构建文件夹(并清理您的gradle缓存)但我相当肯定这个问题不会消失。
如果需要所有这些依赖项,那么您将不得不使用您提到的路由,多路径或缩小调试版本。 Multi-dex应该没问题,不应该导致任何不可预见的问题,而缩小会降低你的构建速度,并可能导致Android Studio变得不稳定(特别是即时运行/应用更改!)
祝你好运,从中获取的一件事是保持你的依赖关系干净和精确,只在绝对需要时添加,如果所有其他方法都失败了,multi-dex就是你的朋友。
我建议使用multidex构建应用程序,然后从新的apk中从多个dex文件中提取方法ID,并从旧的single-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名称修改之前比较列表。
在阅读了您的问题后,我只能建议尝试使缓存失效并重新启动,然后使用此强制刷新您的依赖项。
./gradlew build --refresh-dependencies
作为你的问题,我不得不删除build
文件夹和*.iml
文件(Android Studio项目文件),我必须重新创建项目,然后构建,然后所有工作再次正常。
以上是关于无法将请求的类放在单个dex文件中,即使对于之前编译正常的早期提交也是如此的主要内容,如果未能解决你的问题,请参考以下文章