এই নিবন্ধে, আমরা Android এ মাল্টি-লাইব্রেরি প্রকল্প সম্পর্কে কথা বলতে যাচ্ছি। এটি সাধারণ কিছু নয়, তবে সাধারণের বাইরেও কিছু নয়।
আপনি আপনার কাজের লাইনে মাল্টি-লাইব্রেরি প্রকল্পগুলি দেখতে পেয়েছেন, বা আপনি আরও ভাল কাঠামো এবং সংগঠনের জন্য আপনার লাইব্রেরিটিকে সাব-মডিউলে রূপান্তর করতে খুঁজছেন। যাই হোক না কেন, ডাইভিং করার আগে আপনার সামনে কী রয়েছে তা আপনার ভালভাবে সচেতন হওয়া উচিত।
অ্যান্ড্রয়েডে আপনার নিজের লাইব্রেরি লেখা ঝরঝরে। আপনি এমন কিছু কোড লেখার সুযোগ পাবেন যা অন্যান্য বিকাশকারীদের (বা এমনকি নিজেকেও) সাহায্য করতে পারে।
যেহেতু লাইব্রেরিগুলি নিজেরাই একটি স্বতন্ত্র প্রকল্প হতে পারে না, সেগুলি সাধারণত একটি অ্যাপ্লিকেশন সহ একটি প্রকল্পে যুক্ত থাকে। এটি লাইব্রেরি বিকাশকে একটি সাধারণ প্রক্রিয়া হতে দেয় যেখানে আপনি একটি বৈশিষ্ট্য যোগ করেন/একটি বাগ সংশোধন করেন এবং তারপরে আপনি প্রকল্পে থাকা অ্যাপ্লিকেশনটির সাথে সরাসরি এটি পরীক্ষা করতে পারেন। এইভাবে, একজন বিকাশকারী কীভাবে আপনার লাইব্রেরি সংহত করবে (স্থানীয় উপায়ে) অনুকরণ করে৷
কিন্তু, যদি আপনার লাইব্রেরি অন্য লাইব্রেরির উপর নির্ভর করে যা আপনি বিকাশ করছেন?
আপনি যদি এটি সম্পর্কে সচেতন না হন তবে আপনার জানা উচিত যে একটি লাইব্রেরি (পড়ুন aar) এর মধ্যে অন্য স্থানীয় লাইব্রেরি থাকতে পারে না। এটি দূরবর্তীভাবে লাইব্রেরির উপর নির্ভর করতে পারে (নির্ভরতার মাধ্যমে), তবে স্থানীয় কিছুতে নয়।
এটি অ্যান্ড্রয়েডে সমর্থিত নয়, এবং কয়েক বছর ধরে কিছু সমাধান পপ আপ করার সময় (FatAar), এগুলি সর্বদা সমস্যার সমাধান করে না এবং আপ টু ডেট নয়। এমনকি একটি Google ইস্যু ট্র্যাকারও এই বৈশিষ্ট্যটির জন্য অনুরোধ করছে যা বেশ কিছুদিন ধরে খোলা আছে এবং সম্প্রদায়ের কাছ থেকে প্রচুর মনোযোগ পাচ্ছে। তবে আসুন সনাক্ত করি কোন দেয়াল আমরা ভাঙতে পারি আর কোনটি পারি না।
কল্পনা করুন আপনার প্রকল্পের অনুক্রমটি এইরকম দেখাচ্ছে:
-- App
|
-- OuterLib
|
--- InnerLib
সুতরাং, যেহেতু InnerLib আপনার মূল প্রকল্পের অংশ হতে পারে না, এটি কোথায় থাকতে পারে? এবং এছাড়াও InnerLib-এর মধ্যে বৈশিষ্ট্যগুলি বিকাশ করার সময় আপনি কীভাবে স্থানীয়ভাবে কাজ করতে সক্ষম হবেন?
আমরা এই নিবন্ধে এই প্রশ্নের উত্তর দিতে যাচ্ছি।
গিট সাবমডিউল
বেশিরভাগ প্রযুক্তিগত সমস্যার জন্য, সবসময় শুধুমাত্র একটি সমাধান নেই। সাধারণত, আরো আছে, কিন্তু প্রতিটি সমাধান তার ত্রুটি আছে. দিনের শেষে আপনি কোন ত্রুটিগুলির সাথে জীবনযাপন করতে বেশি স্বাচ্ছন্দ্য বোধ করেন তা সবই একটি প্রশ্ন৷
আমাদের প্রথম প্রশ্নের উত্তর দিতে, InnerLib কোথায় থাকতে পারে, আমাদের কাছে বেশ কয়েকটি বিকল্প রয়েছে:
- ইনারলিবকে আমাদের মূল প্রকল্পের একটি সাবমডিউল করুন
- ইনারলিবকে তার নিজস্ব একটি দূরবর্তী নির্ভরতা করুন
আপনি যদি গিট-এ সাবমডিউলগুলি সম্পর্কে সচেতন না হন তবে তাদের সাথে নিজেকে পরিচিত করার জন্য গিটের ডকুমেন্টেশন একটি ভাল জায়গা। এটি থেকে উদ্ধৃতি (প্রথম অনুচ্ছেদ):
এটি প্রায়শই ঘটে যে একটি প্রকল্পে কাজ করার সময়, আপনাকে এটির মধ্যে থেকে অন্য একটি প্রকল্প ব্যবহার করতে হবে। 👉 সম্ভবত এটি একটি লাইব্রেরি যা তৃতীয় পক্ষ তৈরি করেছে বা আপনি আলাদাভাবে বিকাশ করছেন এবং একাধিক অভিভাবক প্রকল্পে ব্যবহার করছেন। 👈 এই পরিস্থিতিতে একটি সাধারণ সমস্যা দেখা দেয়:আপনি দুটি প্রকল্পকে আলাদা হিসাবে বিবেচনা করতে সক্ষম হতে চান তবে এখনও একটিকে অন্যটির মধ্যে থেকে ব্যবহার করতে সক্ষম হবেন।
এই অনুচ্ছেদটি আমাদের দেখায় যে এটি ঠিক আমাদের ব্যবহারের ক্ষেত্রে। একটি সাবমডিউল ব্যবহার করার সুবিধা রয়েছে। আপনার সমস্ত কোড এক জায়গায় রয়েছে, পরিচালনা করা সহজ এবং স্থানীয়ভাবে বিকাশ করা সহজ।
কিন্তু সাবমডিউলের কিছু দুর্বলতা আছে। একটি হল যে আপনার সাবমডিউল কোন শাখার দিকে ইঙ্গিত করছে সে সম্পর্কে আপনাকে সর্বদা সচেতন থাকতে হবে। একটি দৃশ্যকল্প কল্পনা করুন যেখানে আপনি আপনার প্রধান সংগ্রহস্থলের একটি রিলিজ শাখায় আছেন এবং আপনার সাব-মডিউল একটি বৈশিষ্ট্য শাখায় রয়েছে। আপনি যদি লক্ষ্য না করেন, আপনি এমন কিছু দিয়ে আপনার কোডের একটি সংস্করণ প্রকাশ করেন যা উৎপাদনের জন্য প্রস্তুত নয়। ওহো।
এখন বিকাশকারীদের একটি দলের মধ্যে এটি সম্পর্কে চিন্তা করুন. একটি অসতর্ক ভুল ব্যয়বহুল হতে পারে৷
যদি প্রথম বিকল্পটি আপনার জন্য সমস্যাযুক্ত মনে হয়, তাহলে অন্য সংগ্রহস্থলে আপনার লাইব্রেরি হোস্ট করা আপনার দ্বিতীয় পছন্দ। সংগ্রহস্থল সেট আপ করা বেশ সহজ, কিন্তু আপনি এখন স্থানীয়ভাবে কিভাবে কাজ করবেন?
স্থানীয়ভাবে কাজ করা
এখন যেহেতু আমরা আমাদের প্রকল্পটি সঠিকভাবে সেট আপ করেছি, সম্ভবত আমাদের OuterLib build.gradle ফাইলে এর অনুরূপ একটি লাইন থাকবে:
dependencies {
implementation 'url_to_remote_inner_lib_repository'
}
কীভাবে আমরা উন্নয়ন চক্রকে দক্ষ এবং সহজে কাজ করতে পারি? আমরা যদি InnerLib-এ কিছু বৈশিষ্ট্য বিকাশ করি, তাহলে আমরা কিভাবে OuterLib-এ জিনিসগুলি পরীক্ষা করব? অথবা আমাদের আবেদনে?
আমাদের আউটারলিব প্রজেক্টে InnerLib .gitignored থাকাকালীন আমাদের আউটারলিব প্রোজেক্টে স্থানীয়ভাবে আমাদের InnerLib আমদানি করা একটি সমাধান হতে পারে। আপনি অ্যান্ড্রয়েড স্টুডিওতে বাম দিকের মেনুতে প্রজেক্টের নামের উপর ডান ক্লিক করে এবং নতুন → মডিউলে গিয়ে খুব সহজেই করতে পারেন।
কীভাবে একটি মডিউল আমদানি করতে হয় (ধাপ 1)
তারপরে যে উইন্ডোটি খোলে, আপনি নীচে বাম দিকে আমদানি বিকল্পটি বেছে নিতে পারেন:
কীভাবে একটি মডিউল আমদানি করতে হয় (ধাপ 2)
এটি এখন পর্যন্ত সহজ এবং সহজ শোনাচ্ছে, কিন্তু ধরা কি?
প্রতিবার যখন আপনি InnerLib-এর অন্তর্গত একটি ফাইল সংশোধন করেন, পরিবর্তনগুলি InnerLib-এর মধ্যে প্রতিফলিত হবে না কারণ এটি উপেক্ষা করা হয়। সুতরাং, প্রতিটি পরিবর্তন আপনি যা করতে চান তা InnerLib-এর ভিতরে ঘটতে হবে এবং তারপরে পরিবর্তনগুলি দেখতে আপনাকে আবার OuterLib-এর ভিতরে আমদানি করতে হবে৷
এটা ঠিক মনে হচ্ছে না। এটি করার আরও ভাল উপায় থাকতে হবে৷
আমাদের settings.gradle-এ মাত্র কয়েকটি লাইন দিয়ে ফাইল, যখন আমরা InnerLib-এ পরিবর্তন করি তখন আমরা নিশ্চিত করতে পারি যে আমাদের ফাইলগুলি সিঙ্কে থাকবে।
যখন আমরা আমাদের প্রকল্পে InnerLib আমদানি করি, তখন Android Studio InnerLib-এর একটি অনুলিপি তৈরি করে এবং ক্যাশে করে। এই কারণেই আমাদের লাইব্রেরির ভিতরে করা প্রতিটি পরিবর্তনের জন্য পুনরায় আমদানি করতে হবে। আমরা Android স্টুডিওকে বলতে পারি যে projectDir ব্যবহার করে ফাইলগুলি কোথায় উল্লেখ করতে হবে৷ বৈশিষ্ট্য
আমাদের settings.gradle দেখতে এরকম কিছু হতে পারে:
include ':outerLib', ':innerLib', ':app'
স্থানীয়ভাবে আমাদের InnerLib রেফারেন্স করতে, আমাদের settings.gradle এর মধ্যে পরিবর্তন করতে হবে:
include ':outerLib', ':innerLib', ':app'
project('innerLib').projectDir = new File('PATH_TO_INNER_LIB')
এই পদ্ধতি ব্যবহার করে, আমাদের InnerLib ফাইলগুলি আমাদের কাজের ডিরেক্টরির সাথে লিঙ্ক করা হবে, তাই আমরা যে পরিবর্তন করি তা অবিলম্বে প্রতিফলিত হবে।
কিন্তু, InnerLib এর দূরবর্তী সংস্করণের সাথে OuterLib-এ স্থানীয়ভাবে কাজ করার সময় আমরা নমনীয়তা চাই। Settings.gradle ফাইলের ভিতরে আমরা উপরে যা লিখেছি তা শুধুমাত্র আমাদের স্থানীয়ভাবে কাজ করার অনুমতি দেবে এবং নিশ্চিতভাবেই আমরা তা করতে চাই না।
ম্যাভেন স্থানীয়
যদি উপরের পদ্ধতিটি আপনার সাথে পুরোপুরি ঠিক না হয় তবে আপনি অন্য একটি গ্রহণ করতে পারেন। ঠিক যেমন আপনি ম্যাভেনের সাথে আপনার লাইব্রেরি সর্বজনীনভাবে প্রকাশ করবেন, আপনি স্থানীয়ভাবে ম্যাভেন স্থানীয়ভাবে একই জিনিস করতে পারেন। ম্যাভেন লোকাল হল সংগ্রহস্থলের একটি সেট যা আপনার মেশিনে স্থানীয়ভাবে বসে।
আপনার মেশিনের অপারেটিং সিস্টেমের উপর নির্ভর করে ম্যাভেনলোকালের জন্য নীচের পথগুলি রয়েছে:
- ম্যাক → /Users/YOUR_USERNAME/.m2
- লিনাক্স → /home/YOUR_USERNAME/.m2
- উইন্ডোজ → C:\Users\YOUR_USERNAME.m2
সংক্ষেপে আপনি আপনার লাইব্রেরি স্থানীয়ভাবে প্রকাশ করতে পারেন এবং তারপর আপনার প্রকল্পে এটির সাথে লিঙ্ক করতে পারেন। এইভাবে করা, আমরা আমাদের প্রকল্পকে InnerLib-এর সাথে লিঙ্ক করতে পারি।
আমাদের প্রকল্পে এই কনফিগারেশনের অনুমতি দেওয়ার জন্য, আমাদের নিম্নলিখিত জিনিসগুলি করতে হবে:
- mavenLocal() যোগ করুন আমাদের সংগ্রহস্থল ধারার ভিতরে একটি সংগ্রহস্থল হিসাবে। এটি আমাদের প্রজেক্টকে স্থানীয়ভাবে সংগ্রহস্থল অনুসন্ধান করার ক্ষমতা কে অনুমতি দেওয়ার জন্য
buildscript {
repositories {
mavenLocal()
}
}
...
allprojects {
repositories {
mavenLocal()
}
}
-
আমাদের InnerLib রেফারেন্স করতে আমাদের নির্ভরতা ধারার মধ্যে আমাদের বাস্তবায়ন লাইন পরিবর্তন করুন যেন আমরা এটিকে দূর থেকে উল্লেখ করছি
-
InnerLib স্থানীয়ভাবে প্রকাশ করার জন্য, আমরা publishingLocally.gradle নামে একটি ফাইল তৈরি করব যাতে নিম্নলিখিতগুলি থাকবে:
apply plugin: 'maven-publish'
project.afterEvaluate {
publishing {
publications {
library(MavenPublication) {
setGroupId groupId //your library package
setArtifactId artifactId
version versionName //I.E. 1.0
artifact bundleDebugAar
pom.withXml {
def dependenciesNode = asNode().appendNode('dependencies')
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', 'your_group_id')
dependencyNode.appendNode('artifactId', 'your_artificat_id')
dependencyNode.appendNode('version', 'your_version')
}
}
}
}
}
- আপনার অ্যাপ্লিকেশন লেভেল build.gradle ফাইলের ভিতরে, লাইন যোগ করুন:
apply from: '/.publishingLocally.gradle
যদি এই বিকল্পটি সত্য হতে একটু বেশি ভালো মনে হয়, এটি . একদিকে, আমরা একটি দূরবর্তী লাইব্রেরির সাথে কাজ করছি এমনভাবে স্থানীয়ভাবে নির্বিঘ্নে জিনিসগুলি বিকাশ করতে পারি। অন্যদিকে, স্থানীয়ভাবে কাজ করার সময় যদি আমরা InnerLib-এর ভিতরে কোনো পরিবর্তন করি, তাহলে তা আবার স্থানীয়ভাবে প্রকাশ করতে হবে। যদিও এটি একটি ব্যয়বহুল কাজ নয়, এটি বারবার ক্লান্তিকর কাজগুলি সম্পাদন করার প্রয়োজন তৈরি করে৷
স্থানীয়ভাবে এবং দূরবর্তীভাবে কাজ করার জন্য একটি সমাধান
যখনই আমরা স্থানীয়ভাবে কোনো পরিবর্তন করি তখনই আমরা আমাদের InnerLib প্যাকেজ পুনরায় প্রকাশ করার ধ্রুবক প্রয়োজন এড়াতে চাই। আমাদের প্রকল্পকে সেই পরিবর্তনগুলি সম্পর্কে সচেতন করার জন্য আমাদের একটি উপায় বের করতে হবে।
স্থানীয়ভাবে কাজ করা বিভাগে, আমরা এটি কীভাবে করতে হবে তা খুঁজে পেয়েছি, কিন্তু settings.gradle ফাইলটি কমিট করার ক্ষেত্রে আমাদের একটি সমস্যা ছিল। এই সমস্যাটি সমাধান করার জন্য যাতে আমরা আমাদের InnerLib এর সাথে স্থানীয়ভাবে এবং দূরবর্তীভাবে কাজ করতে পারি, আমরা একটি প্যারামিটার ব্যবহার করব যা আমরা আমাদের gradle.properties এ সংজ্ঞায়িত করব। ফাইল।
gradle.properties ফাইলটি এমন একটি জায়গা যেখানে আপনি প্রজেক্ট লেভেল সেটিংস সংরক্ষণ করতে পারেন যা আপনার ডেভেলপমেন্ট এনভায়রনমেন্ট কনফিগার করে। এটি নিশ্চিত করতে সাহায্য করে যে একটি দলের সকল ডেভেলপারদের একটি সামঞ্জস্যপূর্ণ উন্নয়ন পরিবেশ রয়েছে।
এই ফাইলের ভিতরে পাওয়া যায় এমন কিছু সেটিংসের সাথে আপনি পরিচিত হতে পারেন যা হল AndroidX সমর্থন (android.useAndroidX=true) বা JVM আর্গুমেন্ট (org.gradle.jvmargs=-Xmx1536m)।
আমাদের পরিস্থিতি সমাধানে সাহায্য করার জন্য, আমরা স্থানীয়ভাবে কাজ করতে চাই কিনা তা নির্দেশ করতে এখানে একটি প্যারামিটার যোগ করতে পারি। এর লাইন বরাবর কিছু:
workingLocally = false
এই প্যারামিটারটি আমাদেরকে স্থানীয়ভাবে বা উৎপাদন কোডের সাথে আমরা কোন সেটিংসের সাথে কাজ করছি তার মধ্যে পার্থক্য করার ক্ষমতা প্রদান করবে। প্রথমে, আমাদের settings.gradle ফাইলে যা আছে তা পরিবর্তন করি এমন অবস্থায় মোড়ানো যা আমাদের প্যারামিটারটি সত্য কিনা তা পরীক্ষা করে:
include ':outerLib', ':innerLib', ':app'
if (workingLocally.booleanValue()) {
project('innerLib').projectDir = new File('PATH_TO_INNER_LIB')
}
এইভাবে, আমরা আমাদের মেশিন থেকে স্থানীয়ভাবে আমাদের InnerLib-এর জন্য ফাইলগুলি পেতে প্রকল্পটিকে নির্দেশ করি।
আরেকটি জায়গা যেখানে আমাদের যুক্তি পরিবর্তন করতে হবে আমাদের build.gradle ফাইলে। এখানে, আমাদের নির্ভরতা ব্লকে দূরবর্তীভাবে আমাদের লাইব্রেরিতে কোড পাওয়ার পরিবর্তে, আমরা স্থানীয়ভাবে এটির উপর নির্ভর করছি কিনা তা নির্দেশ করতে পারি।
dependencies {
if (workingLocally.booleanValue()) {
implementation 'innerLib'
} else {
implementation 'url_to_remote_repository'
}
}
⚠️ সতর্কীকরণ শব্দ:স্থানীয়ভাবে কাজ করার সময় আপনার কখনই gradle.properties ফাইল কমিট করা উচিত নয়।
যাত্রা দীর্ঘ ছিল এবং বেশ ক্লান্তিকর মনে হতে পারে. কিন্তু এখন আমাদের কাছে একাধিক লাইব্রেরি প্রকল্পে স্থানীয়ভাবে এবং দূরবর্তীভাবে কাজ করার জন্য একটি ফুল-প্রুফ সেটআপ রয়েছে৷
আপনি যদি কোন সমস্যার সম্মুখীন হন বা এই বিষয়ে আপনার মতামত দিতে চান তাহলে নির্দ্বিধায় একটি মন্তব্য করুন৷
বিনামূল্যে কোড শিখুন. freeCodeCamp-এর ওপেন সোর্স পাঠ্যক্রম 40,000-এরও বেশি লোককে ডেভেলপার হিসেবে চাকরি পেতে সাহায্য করেছে। শুরু করুন