Bağımlılık çözümleme hatalarını ayıklama

Bir bağımlılık eklediğinizde, orijinal bağımlılığın gerektirdiği bağımlılıklarla ilgili sorunlarla ve farklı bağımlılık sürümleri arasında çakışmalarla karşılaşabilirsiniz. Bağımlılık grafiğinizi nasıl analiz edeceğiniz ve sık karşılaşılan sorunları nasıl çözeceğiniz aşağıda açıklanmıştır.

Özel derleme mantığı içeren bağımlılık çözümü hatalarını düzeltme konusunda yardım için Özel bağımlılık çözümleme stratejileri bölümüne bakın.

Modül bağımlılıklarını görüntüleme

Bazı doğrudan bağımlılıkların kendi bağımlılıkları olabilir. Bunlara geçişli bağımlılıklar denir. Gradle, her bir geçişli bağımlılığı manuel olarak bildirmenizi gerektirmek yerine, bunları sizin için otomatik olarak toplayıp ekler. Gradle Android eklentisi, Gradle'ın belirli bir modül için çözdüğü bağımlılıkların listesini gösteren bir görev sağlar.

Rapor her modül için bağımlılıkları derleme varyantına, test kaynağı kümesine ve sınıf yoluna göre de gruplandırır. Aşağıda, bir uygulama modülünün hata ayıklama derleme varyantına ait çalışma zamanı sınıf yolu ve göstergeli test kaynağı kümesinin sınıf yolunu derleme ile ilgili örnek rapor bulunmaktadır.

debugRuntimeClasspath - Dependencies for runtime/packaging
+--- :mylibrary (variant: debug)
+--- com.google.android.material:material:1.0.0@aar
+--- androidx.appcompat:appcompat:1.0.2@aar
+--- androidx.constraintlayout:constraintlayout:1.1.3@aar
+--- androidx.fragment:fragment:1.0.0@aar
+--- androidx.vectordrawable:vectordrawable-animated:1.0.0@aar
+--- androidx.recyclerview:recyclerview:1.0.0@aar
+--- androidx.legacy:legacy-support-core-ui:1.0.0@aar
...

debugAndroidTest
debugAndroidTestCompileClasspath - Dependencies for compilation
+--- androidx.test.ext:junit:1.1.0@aar
+--- androidx.test.espresso:espresso-core:3.1.1@aar
+--- androidx.test:runner:1.1.1@aar
+--- junit:junit:4.12@jar
...

Görevi çalıştırmak için aşağıdaki adımları uygulayın:

  1. Görünüm > Araç Pencereleri > Gradle'ı seçin (veya araç pencereleri çubuğunda Gradle simgesini tıklayın).
  2. AppName > Tasks > android'i genişletin ve androidDependencies'i çift tıklayın. Gradle görevi yürüttükten sonra, çıkışı görüntülemek için Çalıştır penceresi açılmalıdır.

Gradle'da bağımlılıkları yönetme hakkında daha fazla bilgi için Gradle Kullanıcı Kılavuzu'nda Bağımlılık yönetimi ile ilgili temel bilgiler bölümüne göz atın.

Geçişli bağımlılıkları hariç tutma

Uygulama kapsamı genişledikçe doğrudan ve geçişli bağımlılıklar (uygulamanızın içe aktarılan kitaplıklarının bağımlı olduğu kitaplıklar) gibi çeşitli bağımlılıklar içerebilir. Artık ihtiyacınız olmayan geçişli bağımlılıkları hariç tutmak için exclude anahtar kelimesini aşağıda belirtildiği şekilde kullanabilirsiniz:

Kotlin

dependencies {
    implementation("some-library") {
        exclude(group = "com.example.imgtools", module = "native")
    }
}

Modern

dependencies {
    implementation('some-library') {
        exclude group: 'com.example.imgtools', module: 'native'
    }
}

Geçişli bağımlılıkları test yapılandırmalarından hariç tutma

Belirli geçişli bağımlılıkları testlerinizden hariç tutmanız gerekirse yukarıda gösterilen kod örneği beklendiği gibi çalışmayabilir. Çünkü test yapılandırması (ör. androidTestImplementation) modülün implementation yapılandırmasını genişletir. Yani, Gradle yapılandırmayı çözümlediğinde her zaman implementation bağımlılıkları içerir.

Bu nedenle geçişli bağımlılıkları testlerinizden hariç tutmak için aşağıda gösterildiği gibi yürütme sırasında bunu yapmanız gerekir:

Kotlin

android.testVariants.all {
    compileConfiguration.exclude(group = "com.jakewharton.threetenabp", module = "threetenabp")
    runtimeConfiguration.exclude(group = "com.jakewharton.threetenabp", module = "threetenabp")
}

Modern

android.testVariants.all { variant ->
    variant.getCompileConfiguration().exclude group: 'com.jakewharton.threetenabp', module: 'threetenabp'
    variant.getRuntimeConfiguration().exclude group: 'com.jakewharton.threetenabp', module: 'threetenabp'
}

Not: Test yapılandırmasına özel olan ve diğer yapılandırmalara dahil edilmeyen geçişli bağımlılıkları atlamak için Geçişli bağımlılıkları hariç tutma bölümündeki orijinal kod örneğinde gösterildiği gibi bağımlılık bloğunda exclude anahtar kelimesini kullanmaya devam edebilirsiniz.

Bağımlılık çözümleme hatalarını düzeltme

Uygulama projenize birden fazla bağımlılık eklediğinizde bu doğrudan ve geçişli bağımlılıklar birbiriyle çakışabilir. Android Gradle eklentisi bu çakışmaları sorunsuz bir şekilde çözmeye çalışır ancak bazı çakışmalar, derleme zamanı veya çalışma zamanı hatalarına neden olabilir.

Hangi bağımlılıkların hatalara katkıda bulunduğunu araştırmanıza yardımcı olması için uygulamanızın bağımlılık ağacını inceleyin ve birden fazla kez görünen veya çakışan sürümleri olan bağımlılıkları arayın.

Yinelenen bağımlılığı kolayca belirleyemiyorsanız Android Studio'nun kullanıcı arayüzünü kullanarak kopya sınıfı içeren bağımlılıkları aşağıdaki gibi arayabilirsiniz:

  1. Menü çubuğundan Gezinme > Sınıf'ı seçin.
  2. Pop-up arama iletişim kutusunda Proje olmayan öğeleri dahil et seçeneğinin yanındaki kutunun işaretli olduğundan emin olun.
  3. Yapı hatasında görünen sınıfın adını yazın.
  4. Sonuçları, sınıfı içeren bağımlılıklar için inceleyin.

Aşağıdaki bölümlerde, karşılaşabileceğiniz farklı türlerde bağımlılık çözümü hataları ve bunların nasıl düzeltileceği açıklanmaktadır.

Yinelenen sınıf hatalarını düzeltme

Bir sınıf, çalışma zamanı sınıf yolunda birden fazla kez görünüyorsa aşağıdakine benzer bir hata alırsınız:

Program type already present com.example.MyClass

Bu hata genellikle aşağıdaki durumlardan birinden kaynaklanır:

  • İkili program bağımlılığı, uygulamanızın aynı zamanda doğrudan bağımlılık olarak içerdiği bir kitaplığı içerir. Örneğin, uygulamanız A Kitaplığı ve B Kitaplığı'na doğrudan bağımlılık beyan ediyor, ancak A Kitaplığı B Kitaplığı'nı ikili kodunda zaten içeriyor.
    • Bu sorunu çözmek için doğrudan bağımlılık olarak B Kitaplığı'nı kaldırın.
  • Uygulamanız hem yerel bir ikili program bağımlılığı hem de aynı kitaplıkta uzaktan ikili program bağımlılığı bulunuyor.
    • Bu sorunu çözmek için ikili bağımlılıklardan birini kaldırın.

Sınıf yolları arasındaki çakışmaları düzeltme

Gradle, derleme sınıf yolunu çözümlediğinde önce çalışma zamanı sınıf yolunu çözümler ve sonucu kullanarak derleme sınıf yoluna hangi bağımlılık sürümlerinin eklenmesi gerektiğini belirler. Diğer bir deyişle, çalışma zamanı sınıf yolu, aşağı akış sınıf yollarındaki özdeş bağımlılıklar için gerekli sürüm numaralarını belirler.

Uygulamanızın çalışma zamanı sınıf yolu, Gradle'ın, uygulamanın test APK'sı için çalışma zamanı sınıf yolundaki bağımlılıkları eşleştirmek için ihtiyaç duyduğu sürüm numaralarını da belirler. Sınıf yollarının hiyerarşisi Şekil 1'de açıklanmıştır.

Şekil 1. Birden fazla sınıf yolunda görünen bağımlılıkların sürüm numaraları bu hiyerarşiye göre eşleşmelidir.

Örneğin, uygulamanız implementation bağımlılık yapılandırmasını kullanan bir bağımlılık sürümü içerdiğinde ve bir kitaplık modülü runtimeOnly yapılandırmasını kullanarak bağımlılığın farklı bir sürümünü içerdiğinde, aynı bağımlılığın farklı sürümlerinin birden fazla sınıf yolunda göründüğü bir çakışma meydana gelebilir.

Android Graadle eklentisi 3.3.0 ve sonraki sürümleri, çalışma zamanınızdaki bağımlılıkları çözümlerken ve zaman sınıf yollarını derlerken belirli aşağı akış sürüm çakışmalarını otomatik olarak düzeltmeye çalışır. Örneğin, çalışma zamanı sınıf yolu, Kitaplık A sürüm 2.0'ı, derleme sınıf yolu ise Kitaplığı A sürüm 1.0'ı içeriyorsa eklenti, hataları önlemek için derleme sınıf yoluna olan bağımlılığı otomatik olarak Kitaplık A sürüm 2.0 ile günceller.

Bununla birlikte, çalışma zamanı sınıf yolu, Kitaplık A sürüm 1.0'ı ve derleme sınıf yolu, Kitaplık A sürüm 2.0'ı içeriyorsa eklenti, derleme sınıf yolunun bağımlılığını Kitaplık A sürüm 1.0'a düşürmez ve yine de aşağıdakine benzer bir hata alırsınız:

Conflict with dependency 'com.example.library:some-lib:2.0' in project 'my-library'.
Resolved versions for runtime classpath (1.0) and compile classpath (2.0) differ.

Bu sorunu çözmek için aşağıdakilerden birini yapın:

  • Bağımlılığın istediğiniz sürümünü, kitaplık modülünüze api bağımlılığı olarak ekleyin. Yani bağımlılığı yalnızca kitaplık modülünüz tanımlar ancak uygulama modülü de geçişli olarak kendi API'sine erişebilir.
  • Alternatif olarak her iki modülde de bağımlılığı bildirebilirsiniz ancak her modülün bağımlılığın aynı sürümünü kullandığından emin olmanız gerekir. Her bir bağımlılığın sürümlerinin projeniz boyunca tutarlı kalmasını sağlamak için proje genelinde mülkler yapılandırmayı düşünün.