Uygulamanızda API 20 veya daha düşük minSdk
sürümü varsa ve
kitaplığın başvuruda bulunduğu kitaplık 65.536 yöntemi aştığında,
uygulamanızın Android derleme mimarisinin sınırına ulaştığını gösterir:
trouble writing output: Too many field references: 131000; max is 65536. You may try using --multi-dex option.
Derleme sisteminin daha eski sürümleri, aynı sorun:
Conversion to Dalvik format failed: Unable to execute dex: method ID not in [0, 0xffff]: 65536
Bu hata koşullarında ortak bir sayı gösterilir: 65536. Bu numara kullanabileceğiniz toplam referans sayısını tek bir Dalvik Yürütülebilir (DEX) bayt kodu dosyasındaki kod tarafından çağrılır. Bu sayfada, paydaşlara iletmek için multidex adlı bir uygulama yapılandırmasını etkinleştirmenizi sağlar. kullanarak birden fazla DEX dosyası oluşturabilir ve okuyabilirsiniz.
64K referans sınırı hakkında
Android uygulaması (APK) dosyaları, Dalvik Yürütülebilir (DEX) dosyalar: Uygulamanızı çalıştırmak için kullanılan derlenmiş kodu içerir. Dalvik Yürütülebilir teknik özelliği, tek bir DEX dosyasında 65.536'ya (Android dahil olmak üzere) referans verilebilir. ve yöntemlerini kendi kodunuza da ekleyebilirsiniz.
bağlamındaki kilo veya K terimi, 1024 (veya 2^10). 65.536, 64x1024'e eşit olduğundan bu sınıra _64K referans sınırı_.Android 5.0'dan önceki Multidex desteği
Platformun Android 5.0'dan (API düzeyi 21) önceki sürümlerinde Dalvik kullanılır
çalışma zamanına bağlı olarak daha iyidir. Dalvik, uygulamaları varsayılan olarak tek bir
APK başına classes.dex
bayt kod dosyası. Bunu önlemek için
sınırlı olması durumunda, multidex kitaplığını modül düzeyindeki build.gradle
öğesine ekleyin veya
build.gradle.kts
dosya:
Eski
dependencies { def multidex_version = "2.0.1" implementation "androidx.multidex:multidex:$multidex_version" }
Kotlin
dependencies { val multidex_version = "2.0.1" implementation("androidx.multidex:multidex:$multidex_version") }
Bu kitaplık, uygulamanızın birincil DEX dosyasının bir parçası haline gelir ve ardından ek DEX dosyalarına ve içerdikleri koda erişimi yönetir. Bu kitaplığın mevcut sürümlerini görüntülemek için bkz. çokludex sürümleri.
Daha fazla bilgi için uygulamanızı multidex için yapılandırın.Android 5.0 ve sonraki sürümler için Multidex desteği
Android 5.0 (API düzeyi 21) ve sonraki sürümlerde,
APK dosyalarından birden fazla DEX dosyasının yüklenmesini yerel olarak destekler. SANATÇILAR
uygulama yükleme anında önceden derleme yapar,
classesN.dex
dosya oluşturup bunları tek bir dosyada derliyor
için OAT dosyası
teknikler de vardır. Dolayısıyla, minSdkVersion
21 veya üzeri bir değerse multidex varsayılan olarak etkindir ve multidex kitaplığına ihtiyacınız yoktur.
Android 5.0 hakkında daha fazla bilgi için çalışma zamanı için Android Runtime (ART) ve Dalvik bilgilerini okuyun.
Not: Uygulamanızı Android Studio kullanarak çalıştırırken derleme, dağıtım yaptığınız hedef cihazlara göre optimize edilir. Buna, hedef cihazlar çalışırken multidex'in etkinleştirilmesi de dahildir. Android 5.0 ve sonraki sürümler. Bu optimizasyon yalnızca Android Studio için hâlâ sürüm derlemenizi yapılandırmanız gerekebilir 64K sınırını aşmamak için çokludex kullanın.
64K sınırından kaçının.
Uygulamanızı 64K veya daha fazla yöntem referansının kullanılmasını etkinleştirecek şekilde yapılandırmadan önce tarafından tanımlanan yöntemler de dahil olmak üzere uygulama kodunuz tarafından çağrılan toplam referans sayısını azaltmak için veya eklenmiş kitaplıklar olabilir.
Aşağıdaki stratejiler, DEX referans sınırına ulaşmaktan kaçınmanıza yardımcı olabilir:
- Uygulamanızın doğrudan ve geçişli bağımlılıklarını inceleme
- Uygulamanıza eklediğiniz büyük bir kitaplık bağımlılığının değerinin kod miktarından ağır olup olmadığını düşünün eklenip eklenmediğini kontrol edin. Sık karşılaşılan ancak sorunlu bir kalıp, çok büyük bir kitaplık eklemektir. çünkü birkaç yardımcı yöntemi faydalı oldu. Uygulama kodu bağımlılıklarını azaltmak çoğu zaman işe yarar DEX referans sınırından kaçınmış olursunuz.
- Kullanılmayan kodları R8 ile kaldırın
- R8'i çalıştırmak için kod küçültmeyi etkinleştirin oluşturmanız önerilir. Şunları yaptığınızdan emin olmak için küçültmeyi etkinleştirin: APK'larınızla kullanılmayan kod göndermiyor. Kod daraltma doğru yapılandırıldıysa kullanılmayan kod ve kaynakları da bağımlılıklarınızdan kaldırabilir.
Bu teknikleri kullanmak APK'nızın genel boyutunu küçültmenize ve uygulamanızda çokludex ihtiyacını ortadan kaldırın.
Uygulamanızı multidex için yapılandırma
Not:minSdkVersion
değeriniz 21 veya daha yüksek bir değere ayarlanmışsa multidex varsayılan olarak etkinleştirilir.
ve multidex kitaplığına ihtiyacınız yok.
minSdkVersion
değeriniz 20 veya daha düşük bir değere ayarlanırsa
şunu kullanmalıdır:
multidex kitaplığı'na
uygulama projenizde yapılan aşağıdaki değişiklikler:
-
Modül düzeyindeki
build.gradle
dosyasını şu şekilde değiştirin: çokludex'i etkinleştirin ve çokludex kitaplığını aşağıda gösterildiği gibi bağımlılık olarak ekleyin:Eski
android { defaultConfig { ... minSdkVersion 15 targetSdkVersion 33 multiDexEnabled true } ... } dependencies { implementation "androidx.multidex:multidex:2.0.1" }
Kotlin
android { defaultConfig { ... minSdk = 15 targetSdk = 33 multiDexEnabled = true } ... } dependencies { implementation("androidx.multidex:multidex:2.0.1") }
Application
geçersiz kılma durumunuza bağlı olarak sınıfını kullanmak istiyorsanız aşağıdakilerden birini gerçekleştirin:Application
ayarını geçersiz kılmazsanız sınıfını değiştirmek için manifest dosyanızıandroid:name
<application>
etiketi şu şekildedir:<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myapp"> <application android:name="androidx.multidex.MultiDexApplication" > ... </application> </manifest>
Application
ayarını geçersiz kılarsanız sınıfını,MultiDexApplication
öğesini aşağıdaki gibi uzatacak şekilde değiştirin:Kotlin
class MyApplication : MultiDexApplication() {...}
Java
public class MyApplication extends MultiDexApplication { ... }
Application
ayarını geçersiz kılarsanız ancak temel sınıfı değiştirmek mümkün değilse bunun yerineattachBaseContext()
yöntemini geçersiz kılın ve etkinleştirmek içinMultiDex.install(this)
yöntemini çağırın multidex:Kotlin
class MyApplication : SomeOtherApplication() { override fun attachBaseContext(base: Context) { super.attachBaseContext(base) MultiDex.install(this) } }
Java
public class MyApplication extends SomeOtherApplication { @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); MultiDex.install(this); } }
Dikkat: Yürütme Yansıma yoluyla
MultiDex.install()
veya başka bir kodMultiDex.install()
tamamlanmadan önce JNI adresine gönderin. Multidex izleme, bu çağrıları takip etmediğindenClassNotFoundException
veya doğrulama hataları (DEX dosyaları arasındaki hatalı sınıf bölümü nedeniyle)
Artık uygulamanızı oluşturduğunuzda Android geliştirme araçları birincil bir DEX oluşturur.
dosyası (classes.dex
) ve destekleyen DEX dosyaları
(classes2.dex
, classes3.dex
vb.) ekleyebilirsiniz.
Ardından, derleme sistemi tüm DEX dosyalarını APK'nıza paketler.
Çalışma zamanında, sadece ana aramada
classes.dex
dosyası yüklediğinizde, multidex API'ler tüm web sayfalarını aramak için özel bir sınıf yükleyici
yöntemleriniz için kullanılabilir DEX dosyaları oluşturun.
Multidex kitaplığıyla ilgili sınırlamalar
Multidex kitaplığının bilinen bazı sınırlamaları vardır. Kitaplığı, uygulama derleme yapılandırmanıza eklerken aşağıdakileri göz önünde bulundurun:
- Başlatma sırasında DEX dosyalarının bir cihazın veri bölümüne yüklenmesi karmaşıktır ve ikincil DEX dosyaları büyükse Uygulama Yanıt Vermiyor (ANR) hatalarına neden olabilir. Alıcı: bu sorunu önleyin, içeriği en aza indirmek için kod küçültmeyi etkinleştirin DEX dosyalarının boyutunu büyütebilir ve kodun kullanılmayan bölümlerini kaldırabilirsiniz.
- Android 5.0'dan (API düzeyi 21) önceki sürümlerde çalışırken
multidex, doğrusal sınırı aşmak için yeterli değildir (sorun 37008143). Bu sınır şu tarihte artırıldı:
Android 4.0 (API düzeyi 14) yüklü ancak bu da sorunu tamamen çözmedi.
Android 4.0'dan daha düşük sürümlerde, DEX endeksi sınırına ulaştı. Şundan daha düşük API düzeylerini hedefliyorsanız: 14. Platformun bu sürümlerinde kapsamlı bir test yapın çünkü uygulamanız başlangıçta veya belirli sınıf grupları yüklenirken sorun yaşıyorsa.
Kod daraltma ortadan kaldırabilirsiniz.
Birincil DEX dosyasında gerekli sınıfları bildirme
Derleme araçları, multimedya uygulamaları için her DEX dosyasını oluştururken
birincil DEX'te hangi sınıfların gerektiğini belirlemek için karmaşık karar alma süreçleri
ekleyerek uygulamanızın başarılı bir şekilde başlatılmasını sağlayabilirsiniz. Zorunlu olan herhangi bir sınıfsa
birincil DEX dosyasında sağlanmamışsa uygulamanız kilitleniyorsa
java.lang.NoClassDefFoundError
hatasıyla.
Derleme araçları, doğrudan uygulamanızdan erişilen kodun kod yollarını tanır girin. Ancak bu sorun, kod yolları daha az görünür olduğunda (ör. kullandığınız bir kitaplıkta ve karmaşık bağımlılıkları ifade eder. Örneğin, kodda iç gözlem veya çağrı kullanılıyorsa sınıfları farklı bir şekilde tanınmayabilir. birincil DEX dosyasında olması gerekir.
java.lang.NoClassDefFoundError
alırsanız:
birincil DEX'te gerekli olan ek sınıfları manuel olarak belirtmelidir
dosyasını derleme türünüzde multiDexKeepProguard
özelliğiyle tanımlayarak oluşturun. Bir sınıf
multiDexKeepProguard
dosyasını, ardından bu sınıfı
birincil DEX dosyasına eklenir.
multiDexKeepProGuard mülkü
multiDexKeepProguard
dosyası, ProGuard ile aynı biçimi kullanır ve
tüm ProGuard dilbilgisi. Uygulamanızda nelerin depolandığını nasıl özelleştireceğinizle ilgili daha fazla bilgi için
Hangi kodun saklanacağını özelleştirin.
multiDexKeepProguard
ürününde belirttiğiniz dosya -keep
içermelidir
seçenekleri kullanılabilir. Örneğin,
-keep com.example.MyClass.class
Şu adla bir dosya oluşturabilirsiniz:
multidex-config.pro
gibi görünen kod:
-keep class com.example.MyClass -keep class com.example.MyClassToo
Bir paketteki tüm sınıfları belirtmek istiyorsanız dosya aşağıdaki gibi görünür:
-keep class com.example.** { *; } // All classes in the com.example package
Ardından bu dosyayı aşağıdaki şekilde bir derleme türü için tanımlayabilirsiniz:
Eski
android { buildTypes { release { multiDexKeepProguard file('multidex-config.pro') ... } } }
Kotlin
android { buildTypes { getByName("release") { multiDexKeepProguard = file("multidex-config.pro") ... } } }
Geliştirme derlemelerinde multidex'i optimize edin
Multidex yapılandırması, derleme işlemede önemli ölçüde artış gerektirir çünkü derleme sisteminin hangi sınıfların mutlaka birincil DEX dosyasına ve hangi sınıfların ikincil DEX dosyaları olabilir. Yani, genellikle multidex kullanan artımlı derlemeler ve geliştirme sürecinizi yavaşlatabilir.
Artımlı derleme sürelerini azaltmak için
önceden ekleme özelliğiyle derlemeler arasında multidex çıktılarını yeniden kullanın.
Dizine ekleme için yalnızca Android 5.0'da kullanılabilen bir ART biçimi kullanılır.
(API düzeyi 21) ve sonraki sürümler. Android Studio kullanıyorsanız IDE, otomatik olarak önceden ekleme özelliğini kullanır
.
Ancak Gradle derlemelerini komut satırından çalıştırıyorsanız
Önceden dizine eklemeyi etkinleştirmek için minSdkVersion
- 21 veya daha yüksek bir sayı girin.
minSdkVersion
için farklı değerlere
gösterildiği gibi:
Eski
android { defaultConfig { ... multiDexEnabled true // The default minimum API level you want to support. minSdkVersion 15 } productFlavors { // Includes settings you want to keep only while developing your app. dev { // Enables pre-dexing for command-line builds. When using // Android Studio 2.3 or higher, the IDE enables pre-dexing // when deploying your app to a device running Android 5.0 // (API level 21) or higher, regardless of minSdkVersion. minSdkVersion 21 } prod { // If you've configured the defaultConfig block for the production version of // your app, you can leave this block empty and Gradle uses configurations in // the defaultConfig block instead. You still need to include this flavor. // Otherwise, all variants use the "dev" flavor configurations. } } buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { implementation "androidx.multidex:multidex:2.0.1" }
Kotlin
android { defaultConfig { ... multiDexEnabled = true // The default minimum API level you want to support. minSdk = 15 } productFlavors { // Includes settings you want to keep only while developing your app. create("dev") { // Enables pre-dexing for command-line builds. When using // Android Studio 2.3 or higher, the IDE enables pre-dexing // when deploying your app to a device running Android 5.0 // (API level 21) or higher, regardless of minSdkVersion. minSdk = 21 } create("prod") { // If you've configured the defaultConfig block for the production version of // your app, you can leave this block empty and Gradle uses configurations in // the defaultConfig block instead. You still need to include this flavor. // Otherwise, all variants use the "dev" flavor configurations. } } buildTypes { getByName("release") { isMinifyEnabled = true proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro") } } } dependencies { implementation("androidx.multidex:multidex:2.0.1") }
Derleme hızlarını iyileştirmeye yardımcı olacak daha fazla stratejiyi Android Studio'dan veya Derleme hızınızı optimize etme bölümünü okuyun. Derleme varyantlarını kullanma hakkında daha fazla bilgi için bkz. Derleme varyantlarını yapılandırın.
İpucu: Farklı cihazlar için farklı derleme varyantlarınız varsa
çokludex gereksinimleri varsa her biri için farklı bir manifest dosyası sağlayabilirsiniz
için yalnızca API düzeyi 20 ve önceki sürümler için olan dosya
<application>
etiket adı. Ayrıca transkriptinizi
Her varyant için farklı bir Application
alt sınıfı oluşturun.
API düzeyi 20 ve önceki sürümlerin altındaki alt sınıf, MultiDexApplication
sınıfını veya
MultiDex.install(this)
numaralı telefonu arar.
Multidex uygulamalarını test etme
Multidex uygulamaları için araç testleri yazdığınızda ek yapılandırma gerekmez
bir
MonitoringInstrumentation
veya bir
AndroidJUnitRunner
enstrümantasyon. Başka bir
Instrumentation
onCreate()
yöntemini aşağıdaki kodla geçersiz kılmanız gerekir:
Kotlin
fun onCreate(arguments: Bundle) { MultiDex.install(targetContext) super.onCreate(arguments) ... }
Java
public void onCreate(Bundle arguments) { MultiDex.install(getTargetContext()); super.onCreate(arguments); ... }