डिपेंडेंसी रिज़ॉल्यूशन से जुड़ी गड़बड़ियां डीबग करना

कोई डिपेंडेंसी जोड़ने पर, आपको डिपेंडेंसी के साथ समस्याएं आ सकती हैं ओरिजनल डिपेंडेंसी से तय होता है और इसकी वजह से, अलग-अलग डिपेंडेंसी वर्शन में विरोधाभास होता है. डिपेंडेंसी ग्राफ़ का विश्लेषण करने और आम तौर पर होने वाली समस्याओं को ठीक करने का तरीका यहां बताया गया है.

कस्टम बिल्ड वाली डिपेंडेंसी रिज़ॉल्यूशन की गड़बड़ियों को ठीक करने के बारे में दिशा-निर्देश पाने के लिए लॉजिक, देखें पसंद के मुताबिक डिपेंडेंसी रिज़ॉल्यूशन की रणनीतियां.

मॉड्यूल डिपेंडेंसी देखें

कुछ डायरेक्ट डिपेंडेंसी की अपनी डिपेंडेंसी हो सकती है. इन्हें कहा जाता है ट्रांज़िव डिपेंडेंसी. आपको मैन्युअल रूप से हर एलान की जानकारी देने के बजाय, ट्रांज़िटिव डिपेंडेंसी, Gradle अपने-आप इकट्ठा करता है और उन्हें आपके लिए जोड़ता है. Gradle के लिए Android प्लग इन एक ऐसा टास्क देता है जो किसी दिए गए मॉड्यूल के लिए, Gradle डिपेंडेंसी रिज़ॉल्व हो जाता है.

हर मॉड्यूल के लिए, रिपोर्ट साथ ही, बिल्ड वैरिएंट, टेस्टिंग सोर्स सेट, और क्लासपाथ का इस्तेमाल करें. ऐप्लिकेशन मॉड्यूल के रनटाइम की सैंपल रिपोर्ट यहां दी गई है इसके डीबग बिल्ड वैरिएंट का क्लासपाथ और इसके इंस्ट्रुमेंटेड क्लासपाथ को कंपाइल करें टेस्ट सोर्स सेट.

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
...

टास्क को चलाने के लिए, नीचे दिया गया तरीका अपनाएं:

  1. देखें > टूल की विंडो > Gradle (या क्लिक करें टूल विंडो बार में, Gradle ).
  2. बड़ा करें AppName > टास्क > android और androidDependencies पर दो बार क्लिक करें. Gradle के लागू होने के बाद टास्क है, तो आउटपुट दिखाने के लिए Run विंडो खुलेगी.

Gradle में डिपेंडेंसी मैनेज करने के बारे में ज़्यादा जानकारी के लिए, डिपेंडेंसी मैनेजमेंट से जुड़ी बुनियादी बातें देखें.

ट्रांज़िटिव डिपेंडेंसी हटाएं

ऐप्लिकेशन के दायरे में आने पर, इसमें कई डिपेंडेंसी शामिल हो सकती हैं. जैसे, डायरेक्ट डिपेंडेंसी और ट्रांज़िटिव डिपेंडेंसी (लाइब्रेरी, जो आपके ऐप्लिकेशन की हैं इंपोर्ट की गई लाइब्रेरी, इन पर निर्भर करती हैं). आपको जिन ट्रांज़िटिव डिपेंडेंसी की अब ज़रूरत नहीं है उन्हें बाहर रखने के लिए, इनका इस्तेमाल करें: exclude कीवर्ड नीचे दिया गया है:

Kotlin

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

ग्रूवी

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

टेस्ट कॉन्फ़िगरेशन से ट्रांज़िटिव डिपेंडेंसी हटाना

अगर आपको अपने टेस्ट से कुछ ट्रांज़िटिव डिपेंडेंसी को हटाना है, तो हो सकता है कि ऊपर दिखाया गया कोड सैंपल उम्मीद के मुताबिक काम न करे. ऐसा इसलिए, क्योंकि कॉन्फ़िगरेशन (उदाहरण के लिए, androidTestImplementation) मॉड्यूल का विस्तार करता है implementation कॉन्फ़िगरेशन. इसका मतलब है कि इसमें हमेशा implementation होता है डिपेंडेंसी जब Gradle कॉन्फ़िगरेशन का समाधान करता है.

इसलिए, अपने टेस्ट से ट्रांज़िटिव डिपेंडेंसी हटाने के लिए, आपको प्रोग्राम चलाने का समय, जैसा कि नीचे दिखाया गया है:

Kotlin

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

ग्रूवी

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

ध्यान दें: आपके पास अब भी exclude कीवर्ड का इस्तेमाल करने का विकल्प है डिपेंडेंसी ब्लॉक में, जैसा कि ट्रांज़िटिव डिपेंडेंसी को बाहर रखना सेक्शन में, टेस्ट के लिए खास तौर पर तय की गई ट्रांज़िटिव डिपेंडेंसी को छोड़ा जा सकता है का कॉन्फ़िगरेशन किया गया है और इसे अन्य कॉन्फ़िगरेशन में शामिल नहीं किया गया है.

डिपेंडेंसी रिज़ॉल्यूशन से जुड़ी गड़बड़ियां ठीक करना

जब अपने ऐप्लिकेशन प्रोजेक्ट में कई डिपेंडेंसी जोड़ी जाती हैं, तो वे डायरेक्ट और ट्रांज़िटिव डिपेंडेंसी का एक-दूसरे से टकराव हो सकता है. Android Gradle प्लगिन इन विवादों को ग्रेसफ़ुल तरीके से हल करने की कोशिश करता है, लेकिन कुछ विवादों की समय या रनटाइम की गड़बड़ियों को कंपाइल करने के लिए.

किन डिपेंडेंसी से गड़बड़ियां हो रही हैं, यह पता लगाने में आपकी मदद करने के लिए, अपने ऐप्लिकेशन के डिपेंडेंसी ट्री का निरीक्षण करें और ऐसी डिपेंडेंसी जो एक से ज़्यादा बार या एक-दूसरे से अलग वर्शन के साथ दिखती हैं.

अगर डुप्लीकेट डिपेंडेंसी की पहचान आसानी से नहीं की जा सकती, तो Android का इस्तेमाल करें डुप्लीकेट क्लास वाली डिपेंडेंसी खोजने के लिए स्टूडियो का यूज़र इंटरफ़ेस इस तरह से:

  1. नेविगेट करें > क्लास चुनें.
  2. पॉप-अप खोज डायलॉग में, पक्का करें कि जो आइटम प्रोजेक्ट नहीं हैं उन्हें शामिल करें चेकबॉक्स पर सही का निशान लगा है.
  3. बिल्ड की गड़बड़ी में दिखने वाली क्लास का नाम लिखें.
  4. क्लास में शामिल डिपेंडेंसी के लिए नतीजों की जांच करें.

इन सेक्शन में, डिपेंडेंसी रिज़ॉल्यूशन के अलग-अलग टाइप के बारे में बताया गया है समस्याओं को ठीक करने का तरीका और उन्हें ठीक करने का तरीका जानें.

क्लास की डुप्लीकेट गड़बड़ियां ठीक करना

अगर रनटाइम क्लासपाथ पर कोई क्लास एक से ज़्यादा बार दिखती है, तो आपको गड़बड़ी ठीक करें:

Program type already present com.example.MyClass

यह गड़बड़ी आम तौर पर, इनमें से किसी एक वजह से होती है:

  • बाइनरी डिपेंडेंसी में एक लाइब्रेरी होती है जिसे आपका ऐप्लिकेशन डायरेक्ट डिपेंडेंसी. उदाहरण के लिए, आपका ऐप्लिकेशन डायरेक्ट डिपेंडेंसी का एलान करता है लाइब्रेरी A और लाइब्रेरी B, लेकिन लाइब्रेरी A में पहले से ही लाइब्रेरी B शामिल है बाइनरी.
    • इस समस्या को हल करने के लिए, लाइब्रेरी B को डायरेक्ट डिपेंडेंसी के तौर पर हटाएं.
  • आपके ऐप्लिकेशन में लोकल बाइनरी डिपेंडेंसी और रिमोट बाइनरी डिपेंडेंसी है: एक ही लाइब्रेरी से.
    • इस समस्या को हल करने के लिए, किसी एक बाइनरी डिपेंडेंसी को हटाएं.

क्लास पाथ के बीच के टकराव को ठीक करना

जब Gradle, कंपाइल क्लासपाथ को रिज़ॉल्व करता है, तो यह पहले रनटाइम को भी रिज़ॉल्व करता है classpath और नतीजे का इस्तेमाल यह तय करने के लिए करता है कि डिपेंडेंसी के कौनसे वर्शन को कंपाइल क्लासपाथ में जोड़ा जाना चाहिए. दूसरे शब्दों में, रनटाइम क्लासपाथ एक जैसी डिपेंडेंसी के लिए ज़रूरी वर्शन नंबर तय करता है डाउनस्ट्रीम क्लास पाथ.

आपके ऐप्लिकेशन का रनटाइम क्लासपाथ, Gradle के वर्शन नंबर भी तय करता है ऐप्लिकेशन की जांच के लिए, रनटाइम क्लासपाथ में डिपेंडेंसी से मेल खाने की ज़रूरत होती है APK के साथ काम करता है. क्लास पाथ की हैरारकी को पहली इमेज में दिखाया गया है.

पहला डायग्राम. डिपेंडेंसी के वर्शन नंबर जो कई क्लासपाथ में दिखते हैं, वे इस कॉलम से मेल खाने चाहिए हैरारकी है.

ऐसा कॉन्फ़्लिक्ट जहां एक ही डिपेंडेंसी के अलग-अलग वर्शन सभी पर दिखते हैं एक से ज़्यादा क्लासपाथ तब आ सकते हैं, जब उदाहरण के लिए, आपके ऐप्लिकेशन में implementation का इस्तेमाल करने वाली डिपेंडेंसी डिपेंडेंसी कॉन्फ़िगरेशन और लाइब्रेरी मॉड्यूल में इसका इस्तेमाल करके डिपेंडेंसी का दूसरा वर्शन शामिल होता है runtimeOnly कॉन्फ़िगरेशन.

आपके रनटाइम पर डिपेंडेंसी का समाधान करते समय और टाइम क्लासपाथ को कंपाइल करते समय, Android Gradle प्लग इन 3.3.0 और इसके बाद वाले वर्शन, कुछ डाउनस्ट्रीम को अपने-आप ठीक करने की कोशिश करते हैं एक ही समय पर बंद किया जा सकता है. उदाहरण के लिए, अगर रनटाइम क्लासपाथ में लाइब्रेरी A शामिल है वर्शन 2.0 और कंपाइल क्लासपाथ में लाइब्रेरी A का 1.0 वर्शन, प्लगिन कंपाइल किए गए क्लासपाथ पर, लाइब्रेरी A के लिए डिपेंडेंसी अपने-आप अपडेट कर देता है वर्शन 2.0 का इस्तेमाल करें.

हालांकि, अगर रनटाइम क्लासपाथ में लाइब्रेरी A वर्शन 1.0 और कंपाइल क्लासपाथ में लाइब्रेरी A का वर्शन 2.0 शामिल है, तो प्लगिन क्लासपाथ को लाइब्रेरी A के वर्शन 1.0 में कंपाइल करें और आपको अब भी नीचे दी गई गड़बड़ी की तरह एक गड़बड़ी:

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.

इस समस्या को हल करने के लिए, इनमें से कोई एक तरीका अपनाएं:

  • डिपेंडेंसी का मनचाहा वर्शन, api डिपेंडेंसी के तौर पर इस तरह शामिल करें: लाइब्रेरी मॉड्यूल का इस्तेमाल करेगा. इसका मतलब है कि सिर्फ़ आपकी लाइब्रेरी मॉड्यूल डिपेंडेंसी का एलान करता है, लेकिन ऐप्लिकेशन मॉड्यूल के पास उसके एपीआई को भी एक जगह से ऐक्सेस करने की सुविधा होगी.
  • इसके अलावा, दोनों मॉड्यूल में डिपेंडेंसी का एलान किया जा सकता है, लेकिन आपको पक्का करें कि हर मॉड्यूल, डिपेंडेंसी के एक ही वर्शन का इस्तेमाल करता हो. इन बातों पर ध्यान दें पूरे प्रोजेक्ट के हिसाब से प्रॉपर्टी कॉन्फ़िगर करना ताकि यह पक्का किया जा सके कि आपके पूरे प्रोजेक्ट में हर डिपेंडेंसी के वर्शन एक जैसे बने रहें.