Uygulamanızın minSdk
API düzeyi 20 veya daha düşükse ve uygulamanız ile referans verdiği kitaplıklar 65.536 yöntemi aşıyorsa uygulamanızın Android derleme mimarisinin sınırına ulaştığını belirten aşağıdaki derleme hatasıyla karşılaşırsınız:
trouble writing output: Too many field references: 131000; max is 65536. You may try using --multi-dex option.
Derleme sisteminin eski sürümleri, aynı sorunun göstergesi olan farklı bir hata bildirir:
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 sayı, tek bir Dalvik yürütülebilir (DEX) bayt kodu dosyasındaki kod tarafından çağrılabilecek toplam referans sayısını ifade eder. Bu sayfada, müzakere becerilerinizi gösteren 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 kadar referans verilebilir (Android dahil olmak üzere) 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ı_ denir.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ı. Bu sınırlamayı aşmak için multidex kitaplığını modül düzeyindeki build.gradle
veya build.gradle.kts
dosyasına ekleyin:
dependencies { def multidex_version = "2.0.1" implementation "androidx.multidex:multidex:$multidex_version" }
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 çoklu paket desteği
Android 5.0 (API düzeyi 21) ve sonraki sürümler, APK dosyalarından birden fazla DEX dosyasının yüklenmesini doğal olarak destekleyen ART adlı bir çalışma zamanı kullanır. 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'yu kullanarak çalıştırdığınızda derleme, dağıttığınız hedef cihazlar için optimize edilir. Hedef cihazlarda Android 5.0 ve sonraki sürümler çalıştırıldığında çoklu dizin etkinleştirme de buna dahildir. Bu optimizasyon yalnızca uygulamanızı Android Studio kullanılarak dağıtırken uygulandığından, 64 KB sınırını aşmamak için sürüm derlemenizi multidex olarak yapılandırmanız gerekebilir.
64K sınırından kaçının.
Uygulamanızı 64.000 veya daha fazla yöntem referansının kullanılmasını sağlayacak şekilde yapılandırmadan önce, uygulama kodunuz tarafından tanımlanan yöntemler veya dahil edilen kitaplıklar dahil olmak üzere uygulama kodunuz tarafından çağrılan toplam referans sayısını azaltmak için adımlar atın.
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 kodunuzdaki bağımlılıkları azaltmak, DEX referans sınırını aşmanızı önlemeye yardımcı olabilir.
- R8 ile kullanılmayan kodları kaldırma
- Sürüm derlemelerinizde R8'i çalıştırmak için kod küçültmeyi etkinleştirin. Şunları yaptığınızdan emin olmak için küçültmeyi etkinleştirin: APK'larınızla kullanılmayan kod göndermiyor. Kod küçültme doğru şekilde yapılandırılmışsa bağımlılıklarınızdan kullanılmayan kodları ve kaynakları da kaldırabilir.
Bu teknikleri kullanmak, APK'nızın genel boyutunu küçültmenize ve uygulamanızda multidex kullanma ihtiyacını önlemenize yardımcı olabilir.
Uygulamanızı multidex için yapılandırma
Not:minSdkVersion
değeriniz 21 veya daha yüksek bir değere ayarlanmışsa çoklu dex varsayılan olarak etkindir ve çoklu dex kitaplığına ihtiyacınız yoktur.
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:android { defaultConfig { ... minSdkVersion 15 targetSdkVersion 33 multiDexEnabled true } ... } dependencies { implementation "androidx.multidex:multidex:2.0.1" }
android { defaultConfig { ... minSdk = 15 targetSdk = 33 multiDexEnabled = true } ... } dependencies { implementation("androidx.multidex:multidex:2.0.1") }
Application
sınıfını geçersiz kılmanıza bağlı olarak aşağıdakilerden birini yapın: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:Application
sınıfı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 çoklu dizeyi etkinleştirmek içinMultiDex.install(this)
'i çağırın:class MyApplication : SomeOtherApplication() { override fun attachBaseContext(base: Context) { super.attachBaseContext(base) MultiDex.install(this) } }
public class MyApplication extends SomeOtherApplication { @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); MultiDex.install(this); } }
Dikkat:
MultiDex.install()
tamamlanmadan önceMultiDex.install()
'yi veya başka bir kodu yansıma veya JNI aracılığıyla yürütmeyin. 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 derleme araçları birincil bir DEX dosyası (classes.dex
) ve gerektiğinde destekleyici DEX dosyaları (classes2.dex
, classes3.dex
vb.) oluşturur.
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şık bir işlemdir 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 Android 4.0'da (API düzeyi 14) artırıldı ancak sorun tamamen çözülmedi.
Android 4.0'tan eski sürümlerde, DEX dizini sınırına ulaşmadan önce linearalloc sınırına ulaşabilirsiniz. Ş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ı tanımlama
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 kitaplığın karmaşık bağımlılıkları olduğunda) ortaya çıkabilir. Örneğin, kodda yerel koddan Java yöntemlerinin iç gözlemi veya çağrılması kullanılıyorsa bu sınıflar birincil DEX dosyasında gerekli olarak tanınmayabilir.
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 ProGuard dil bilgisinin tamamını destekler. Uygulamanızda nelerin tutulacağını özelleştirme hakkında daha fazla bilgi için Hangi kodun tutulacağını özelleştirme başlıklı makaleyi inceleyin.
multiDexKeepProguard
ürününde belirttiğiniz dosya -keep
içermelidir
seçenekleri kullanılabilir. Örneğin,
-keep com.example.MyClass.class
. multidex-config.pro
adlı şu dosyayı oluşturabilirsiniz:
-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:
android { buildTypes { release { multiDexKeepProguard file('multidex-config.pro') ... } } }
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 kısaltmak için ön dexing özelliğini kullanarak derlemeler arasında çoklu dex çıktısını yeniden kullanın.
Ön dex oluşturma işlemi, yalnızca Android 5.0 (API düzeyi 21) ve sonraki sürümlerde kullanılabilen bir ART biçimini kullanır. 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ğerler kullanılır.
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" }
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") }
Android Studio'da veya komut satırında derleme hızlarını artırmaya yardımcı olacak daha fazla strateji öğrenmek için Derleme hızınızı optimize etme başlıklı makaleyi 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:
fun onCreate(arguments: Bundle) { MultiDex.install(targetContext) super.onCreate(arguments) ... }
public void onCreate(Bundle arguments) { MultiDex.install(getTargetContext()); super.onCreate(arguments); ... }