আপনি যখন একটি নির্ভরতা যোগ করেন, তখন আপনি মূল নির্ভরতার জন্য প্রয়োজনীয় নির্ভরতা এবং বিভিন্ন নির্ভরতা সংস্করণগুলির মধ্যে দ্বন্দ্বের সাথে সমস্যার সম্মুখীন হতে পারেন। আপনার নির্ভরতা গ্রাফটি কীভাবে বিশ্লেষণ করবেন এবং উদ্ভূত সাধারণ সমস্যাগুলি সমাধান করবেন তা এখানে।
কাস্টম বিল্ড লজিক জড়িত নির্ভরতা রেজোলিউশন ত্রুটিগুলি ঠিক করার নির্দেশিকা জন্য, কাস্টম নির্ভরতা রেজোলিউশন কৌশলগুলি দেখুন৷
মডিউল নির্ভরতা দেখুন
কিছু প্রত্যক্ষ নির্ভরতার নিজস্ব নির্ভরতা থাকতে পারে। এগুলোকে ট্রানজিটিভ নির্ভরতা বলা হয়। প্রতিটি ট্রানজিটিভ নির্ভরতা আপনাকে ম্যানুয়ালি ঘোষণা করার প্রয়োজন না করে, 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
...
টাস্ক চালানোর জন্য, নিম্নলিখিত হিসাবে এগিয়ে যান:
- View > Tool Windows > Gradle নির্বাচন করুন (বা Gradle-এ ক্লিক করুন টুল উইন্ডোজ বারে)।
- AppName > Tasks > android প্রসারিত করুন এবং androidDependencies-এ ডাবল-ক্লিক করুন। Gradle টাস্কটি কার্যকর করার পরে, রান উইন্ডোটি আউটপুট প্রদর্শনের জন্য খোলা উচিত।
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
কনফিগারেশনকে প্রসারিত করে। অর্থাৎ, যখন Gradle কনফিগারেশনটি সমাধান করে তখন এটি সর্বদা implementation
নির্ভরতা ধারণ করে।
সুতরাং, আপনার পরীক্ষাগুলি থেকে ট্রানজিটিভ নির্ভরতা বাদ দিতে, আপনাকে অবশ্যই তা সম্পাদনের সময় করতে হবে যা নীচে দেখানো হয়েছে:
কোটলিন
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 স্টুডিওর UI ব্যবহার করার চেষ্টা করুন:
- মেনু বার থেকে নেভিগেট > ক্লাস নির্বাচন করুন।
- পপ-আপ অনুসন্ধান ডায়ালগে, অ-প্রকল্প আইটেম অন্তর্ভুক্ত করার পাশের বাক্সটি চেক করা হয়েছে তা নিশ্চিত করুন৷
- বিল্ড ত্রুটিতে প্রদর্শিত ক্লাসের নাম টাইপ করুন।
- ক্লাস অন্তর্ভুক্ত নির্ভরতা জন্য ফলাফল পরিদর্শন করুন.
নিম্নলিখিত বিভাগগুলি বিভিন্ন ধরণের নির্ভরতা রেজোলিউশন ত্রুটিগুলি বর্ণনা করে যা আপনি সম্মুখীন হতে পারেন এবং কীভাবে সেগুলি ঠিক করবেন৷
ডুপ্লিকেট ক্লাস ত্রুটি ঠিক করুন
রানটাইম ক্লাসপথে যদি একটি ক্লাস একাধিকবার উপস্থিত হয়, তাহলে আপনি নিম্নলিখিতগুলির মতো একটি ত্রুটি পাবেন:
Program type already present com.example.MyClass
এই ত্রুটিটি সাধারণত নিম্নলিখিত পরিস্থিতিতেগুলির একটির কারণে ঘটে:
- একটি বাইনারি নির্ভরতা একটি লাইব্রেরি অন্তর্ভুক্ত করে যা আপনার অ্যাপটি সরাসরি নির্ভরতা হিসাবে অন্তর্ভুক্ত করে। উদাহরণস্বরূপ, আপনার অ্যাপ লাইব্রেরি A এবং লাইব্রেরি B-এর উপর সরাসরি নির্ভরতা ঘোষণা করে, কিন্তু লাইব্রেরি A ইতিমধ্যেই লাইব্রেরি B এর বাইনারিতে অন্তর্ভুক্ত করে।
- এই সমস্যাটি সমাধান করতে , সরাসরি নির্ভরতা হিসাবে লাইব্রেরি বি সরান।
- আপনার অ্যাপের একটি স্থানীয় বাইনারি নির্ভরতা এবং একই লাইব্রেরিতে একটি দূরবর্তী বাইনারি নির্ভরতা রয়েছে।
- এই সমস্যাটি সমাধান করতে , বাইনারি নির্ভরতাগুলির একটি সরান।
ক্লাসপাথের মধ্যে দ্বন্দ্ব ঠিক করুন
যখন Gradle কম্পাইল ক্লাসপাথ সমাধান করে, এটি প্রথমে রানটাইম ক্লাসপথের সমাধান করে এবং কম্পাইল ক্লাসপথে নির্ভরতার কোন সংস্করণ যোগ করা উচিত তা নির্ধারণ করতে ফলাফল ব্যবহার করে। অন্য কথায়, রানটাইম ক্লাসপথ ডাউনস্ট্রিম ক্লাসপাথগুলিতে অভিন্ন নির্ভরতার জন্য প্রয়োজনীয় সংস্করণ সংখ্যা নির্ধারণ করে।
আপনার অ্যাপের রানটাইম ক্লাসপাথ অ্যাপের পরীক্ষার APK-এর জন্য রানটাইম ক্লাসপাথের নির্ভরতা মেলানোর জন্য গ্রেডল-এর প্রয়োজনীয় সংস্করণ নম্বরগুলিও নির্ধারণ করে। শ্রেণীপথের শ্রেণিবিন্যাস চিত্র 1 এ বর্ণিত হয়েছে।
একটি দ্বন্দ্ব যেখানে একই নির্ভরতার বিভিন্ন সংস্করণ একাধিক ক্লাসপাথ জুড়ে প্রদর্শিত হতে পারে যখন, উদাহরণস্বরূপ, আপনার অ্যাপ implementation
নির্ভরতা কনফিগারেশন ব্যবহার করে নির্ভরতার একটি সংস্করণ অন্তর্ভুক্ত করে এবং একটি লাইব্রেরি মডিউল runtimeOnly
কনফিগারেশন ব্যবহার করে নির্ভরতার একটি ভিন্ন সংস্করণ অন্তর্ভুক্ত করে।
আপনার রানটাইম এবং কম্পাইল টাইম ক্লাসপাথের উপর নির্ভরতা সমাধান করার সময়, অ্যান্ড্রয়েড গ্রেডল প্লাগইন 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
নির্ভরতা হিসাবে নির্ভরতার পছন্দসই সংস্করণটি অন্তর্ভুক্ত করুন। অর্থাৎ, শুধুমাত্র আপনার লাইব্রেরি মডিউল নির্ভরতা ঘোষণা করে, কিন্তু অ্যাপ মডিউলটিরও তার API-এ অ্যাক্সেস থাকবে, ট্রানজিটিভভাবে। - বিকল্পভাবে, আপনি উভয় মডিউলে নির্ভরতা ঘোষণা করতে পারেন, তবে আপনার নিশ্চিত হওয়া উচিত যে প্রতিটি মডিউল নির্ভরতার একই সংস্করণ ব্যবহার করে। প্রতিটি নির্ভরতার সংস্করণগুলি আপনার প্রকল্প জুড়ে সামঞ্জস্যপূর্ণ থাকে তা নিশ্চিত করতে প্রকল্প-ব্যাপী বৈশিষ্ট্যগুলি কনফিগার করার কথা বিবেচনা করুন।