したがって、Androidプロジェクトの最大メソッド数の制限に達しました。これは、次のエラーメッセージでビルドに失敗します。
エラー:null、要求されたクラスを単一のdexファイルに適合できません(#メソッド:117407> 65536)
メッセージの意味と解決方法(proguardの実行、multidexの有効化など)を理解しています。私の問題は、なぜこのメッセージが突然表示されるのか理解できないことです。私が行っていたのは、冗長な古いコードの一部を削除してビルドをヒットすることでしたが、今、このメッセージが表示されます。
質問1:ライブラリの依存関係を追加していなくても、メソッド数(エラーメッセージによる117407)が突然大規模制限(65536)を超える可能性があるのはなぜですか?実際にコードを削除しましたが、突然5万のメソッドが多すぎますか?
ここが本当に奇妙なところです。APKを分析して問題の原因を突き止めたかったのですが、もちろんビルドできません。したがって、multidexを有効にする代わりに、コードを昨日に戻すことに決めました(これは間違いなく昨日は問題なくビルドできました-私はそれを証明するために自分の電話にアプリを置いています!)、しかし私はそれでもこのビルドエラーメッセージを取得します。どうしてこんなことができるのか分かりません。同じことを数日前に戻してみましたが、同じことです(新しいリポジトリのクローンを作成し、以前のコミットをチェックアウトします)。
だから、質問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でキャッシュ/再起動を無効にしてみました。マルチデックスを有効にしたり、デバッグビルドでプロガードを実行したりする必要はありません。
完全な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の下にいくつかの重い依存関係が表示されます(定義または参照されているメソッド番号を確認する必要があるかどうかわかりません) ?):
これらだけで私は限界に達します。これが突然起こっている理由がまだわかりません:(確かにライブラリを追加していない場合、これらの数値は変更されていないはずですか?
ビルドグラドルファイル全体を確認すると、問題は間違いなく依存関係に起因しています。それらをクリーンアップして、使用しないものをできるだけ多く削除してみてください。おそらく、あなたが制限に非常に近く、それらの依存関係のいずれかが古いバージョンを使用してキャッシュされている可能性があります。ビルドフォルダー全体を削除(およびGradleキャッシュをクリーンアップ)することもできますが、問題が解決しないことは間違いありません。
残念ながらこれらの依存関係のすべてが必要な場合は、マルチデックスまたはミニファイデバッグビルドのいずれかで、言及したルートに進む必要があります。 multi-dexは問題ないはずであり、縮小するとビルドが遅くなり、Android Studioが不安定になる可能性があります(特に、即時実行/変更の適用!))。
幸運、これから取る1つのことは、依存関係を明確かつ正確に保ち、絶対に必要な場合にのみ追加することです。他のすべてが失敗した場合、マルチdexはあなたの友達です。
これをグラドルに追加するだけです(モジュール:アプリ)>> multiDexEnabled true
Android {
defaultConfig {
...
minSdkVersion 21
targetSdkVersion 28
multiDexEnabled true
}
...
}
次に、メニューの[プロジェクトの再構築] => [ビルド]> [プロジェクトの再構築]をクリックします。
あなたの質問を読んだ後、キャッシュを無効にして再起動し、これを使用して依存関係を強制的に更新することをお勧めします。
./gradlew build --refresh-dependencies
あなたの問題として、私はbuild
フォルダーと*.iml
ファイル(Android Studioプロジェクトファイル)を削除する必要がありました。プロジェクトを再作成する必要がありました。その後、ビルドすると、すべて正常に機能しました。
build.gradleアプリ
implementation 'com.Android.support:multidex:2.0.1'
Android {
multiDexEnabled true
}
同じ問題が発生し、解決策は[ファイル]-> [設定]-> [ビルド、実行、配置]-> [インスタントラン]でインスタントランを有効にすることでしたが、これで問題が解決しました。お役に立てば幸いです。
私はこれを試しました。それが役立つことを願って、いくつかのドキュメントで見つけました(URLを忘れました:()
build.gradleアプリ
dependencies {...
grdef multidex_version ='2.0.1'
implementation "androidx.multidex:multidex:$multidex_version"
}...
Multidexを使用してアプリケーションを構築し、新しいapkから複数のdexファイルからメソッドIDを抽出し、古い、単一dex apkからメソッドIDを抽出して、2つのリストを比較することをお勧めします。
おおよそ、次のようなもの:
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
ただし、プロガードを使用している場合は、リストを比較する前に、リバースプロガード名のマングリングを適用する方法を考えなければならない場合があります。