عند إضافة تبعية، قد تواجه مشاكل في التبعيات المطلوبة من التبعية الأصلية، وحالات تعارض بين إصدارات التبعية المختلفة. في ما يلي كيفية تحليل الرسم البياني للتبعيات وحلّ المشاكل الشائعة التي تظهر.
للحصول على إرشادات حول إصلاح أخطاء حلّ التبعيات التي تتضمّن منطق الإنشاء المخصّص، يُرجى الاطّلاع على استراتيجيات حلّ التبعيات المخصّصة.
طلب موجَّه إلى الذكاء الاصطناعي
تصحيح أخطاء حلّ التبعيات
يطلب هذا الطلب المساعدة في تصحيح أخطاء تعارضات التبعيات.
شغِّل هذا الطلب في Android Studio مع فتح build.gradle.
I'm getting the following error in my build: Conflict with dependency. Resolved versions for runtime classpath and compile classpath differ. What changes do I need to make to my dependencies to resolve this error.
عرض تبعيات الوحدة
قد يكون لبعض التبعيات المباشرة تبعيات خاصة بها. ويُطلق على هذه التبعيات اسم التبعيات الانتقالية. بدلاً من أن تطلب منك تحديد كل تبعية متعدّدة، يجمع Gradle هذه التبعية ويضيفها نيابةً عنك. يقدّم المكوّن الإضافي لنظام Gradle المتوافق مع Android مهمة تعرِض قائمة بالادّخارات التي يحلّها Gradle لمكوّن معيّن.
لكل وحدة، يصنِّف التقرير التبعيات أيضًا استنادًا إلى نوع الإصدار ومجموعة مصادر الاختبار وملف مسار التحميل. في ما يلي نموذج تقرير عن ملف VMCLASSPATH لوقت تشغيل وحدة التطبيق لخيار الإصدار المخصّص لتصحيح الأخطاء وملف COMPILATION_CLASSPATH لمجموعة مصادر اختبار instrumented لوحدة التطبيق.
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
...
لتنفيذ المهمة، اتّبِع الخطوات التالية:
- اختَر عرض > نوافذ الأدوات > Gradle (أو انقر على
Gradle
في شريط نوافذ الأدوات).
- وسِّع AppName > المهام > android وانقر مرّتين على androidDependencies. بعد تنفيذ Gradle للمهمة، من المفترض أن تفتح نافذة Run (تشغيل) لعرض الإخراج.
لمزيد من المعلومات عن إدارة التبعيات في Gradle، اطّلِع على أساسيات إدارة التبعيات في دليل مستخدم Gradle.
استبعاد التبعيات الانتقالية
مع توسُّع نطاق التطبيق، يمكن أن يحتوي على عدد من التبعيات، بما في ذلك التبعيات المباشرة والتبعيات غير المباشرة (المكتبات التي تعتمد عليها مكتبات التطبيق المستورَدة).
لاستبعاد التبعيات الانتقالية التي لم تعُد بحاجة إليها، يمكنك استخدام الكلمة الرئيسية
exclude
كما هو موضّح أدناه:
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 الإعدادات.
لذلك، لاستبعاد التبعيات الانتقالية من اختباراتك، عليك إجراء ذلك في وقت ejecutant كما هو موضّح أدناه:
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 Studio للبحث عن التبعيات التي تتضمّن الفئة المكرّرة على النحو التالي:
- اختَر التنقّل > الفئة من شريط القوائم.
- في مربّع الحوار المنبثق للبحث، تأكَّد من وضع علامة في المربّع بجانب تضمين العناصر غير التابعة للمشروع.
- اكتب اسم الفئة التي تظهر في خطأ الإنشاء.
- راجِع النتائج بحثًا عن التبعيات التي تتضمّن الصف.
توضّح الأقسام التالية الأنواع المختلفة من أخطاء حلّ التبعيات التي قد تواجهها وكيفية إصلاحها.
إصلاح أخطاء الصفوف المكرّرة
إذا ظهرت فئة أكثر من مرة في مسار فئة التشغيل، ستظهر لك رسالة خطأ مشابهة لما يلي:
Program type already present com.example.MyClass
يحدث هذا الخطأ عادةً لسبب من الأسباب التالية:
- تتضمّن التبعيات الثنائية مكتبة يتضمّنها تطبيقك أيضًا كأحد
الملحقات المباشرة. على سبيل المثال، يشير تطبيقك إلى تبعية مباشرة لملفَي مكتبة A ومكتبة B، ولكن مكتبة A تتضمّن مكتبة B في ملفها المبرمَج.
- لحلّ هذه المشكلة، عليك إزالة "المكتبة ب" كعنصر تابع مباشر.
- يحتوي تطبيقك على عنصر ثنائي محلي وعنصر ثنائي بعيد يعتمدان على
المكتبة نفسها.
- لحلّ هذه المشكلة، عليك إزالة إحدى التبعيات الثنائية.
حلّ التعارضات بين مسارات الفئات
عندما يحلّ Gradle مسار تجميع الترجمة البرمجية، يحلّ أولاً مسار تجميع وقت التشغيل ويستخدم النتيجة لتحديد إصدارات التبعيات التي يجب إضافتها إلى مسار تجميع الترجمة البرمجية. بعبارة أخرى، يحدِّد ملف مسار التجميع في وقت التشغيل أرقام الإصدارات المطلوبة للتبعيات المتطابقة في ملف مسار التجميع التابع.
يحدِّد مسار حِزم وقت التشغيل لتطبيقك أيضًا أرقام الإصدارات التي يتطلّبها Gradle لمطابقة التبعيات في مسار حِزم وقت التشغيل لملف APK الخاص باختبار التطبيق. يوضّح الشكل 1 التدرّج الهرمي لمسارات الفئات.
الشكل 1: يجب أن تتطابق أرقام إصدارات التبعيات التي تظهر في مسارات فصول متعددة وفقًا لهذا التسلسل الهرمي.
قد يحدث تعارض عندما تظهر إصدارات مختلفة من الملحق نفسه في
مسارات فصول برمجية متعددة، على سبيل المثال، عندما يتضمّن تطبيقك إصدارًا من
ملحق باستخدام implementation
إعداد الملحق
وتتضمّن وحدة مكتبة إصدارًا مختلفًا من الملحق باستخدام الإعداد
runtimeOnly
.
عند حلّ التبعيات في مسارَي classpath وقت التشغيل ووقت الترجمة، يحاول المكوّن الإضافي 3.3.0 والإصدارات الأحدث من Android IDE Gradle حلّ بعض تعارضات الإصدارات المتعلّقة بالإصدارات اللاحقة تلقائيًا. على سبيل المثال، إذا كان مسار تجميع الرموز البرمجية يتضمّن الإصدار 2.0 من المكتبة "أ" ويتضمن مسار تجميع الرموز البرمجية الإصدار 1.0 من المكتبة "أ"، يعدّل المكوّن الإضافي الاعتماد على مسار تجميع الرموز البرمجية تلقائيًا إلى الإصدار 2.0 من المكتبة "أ" لتجنّب حدوث أخطاء.
ومع ذلك، إذا كان مسار تجميع الفصول الدراسية في وقت التشغيل يتضمّن الإصدار 1.0 من المكتبة "أ" وكان مسار تجميع الفصول الدراسية يتضمّن الإصدار 2.0 من المكتبة "أ"، لن يُنزِّل المكوّن الإضافي الإصدار المُعتمَد في مسار تجميع الفصول الدراسية إلى الإصدار 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
في وحدة المكتبة. وهذا يعني أنّ وحدة المكتبة وحدها هي التي تحدّد التبعية، ولكن ستتمكّن أيضًا وحدة التطبيق من الوصول إلى واجهة برمجة التطبيقات بشكل غير مباشر. - بدلاً من ذلك، يمكنك الإفصاح عن الاعتمادية في كلتا المكوّنَين، ولكن عليك التأكّد من أنّ كل مكوّن يستخدم الإصدار نفسه من الاعتمادية. ننصحك بمحاولة ضبط الخصائص على مستوى المشروع لضمان أن تظل إصدارات كل تبعية متسقة في جميع أنحاء مشروعك.