এই পৃষ্ঠাটি আপনাকে দেখায় কিভাবে আপনি একটি একক প্রকল্প থেকে আপনার অ্যাপের বিভিন্ন সংস্করণ তৈরি করতে বিল্ড ভেরিয়েন্ট কনফিগার করতে পারেন এবং কীভাবে আপনার নির্ভরতা এবং সাইনিং কনফিগারেশনগুলি সঠিকভাবে পরিচালনা করবেন।
প্রতিটি বিল্ড ভেরিয়েন্ট আপনার অ্যাপের একটি ভিন্ন সংস্করণ উপস্থাপন করে যা আপনি তৈরি করতে পারেন। উদাহরণস্বরূপ, আপনি আপনার অ্যাপের একটি সংস্করণ তৈরি করতে চাইতে পারেন যা সীমিত সামগ্রীর সাথে বিনামূল্যে, এবং অন্য একটি অর্থপ্রদানের সংস্করণ যাতে আরও অন্তর্ভুক্ত থাকে। আপনি আপনার অ্যাপের বিভিন্ন সংস্করণও তৈরি করতে পারেন যা API স্তর বা অন্যান্য ডিভাইসের বৈচিত্রের উপর ভিত্তি করে বিভিন্ন ডিভাইসকে লক্ষ্য করে।
বিল্ড ভেরিয়েন্টগুলি আপনার বিল্ডের ধরন এবং পণ্যের স্বাদে কনফিগার করা সেটিংস, কোড এবং সংস্থানগুলিকে একত্রিত করতে নিয়মের একটি নির্দিষ্ট সেট ব্যবহার করে গ্রেডলের ফলাফল। যদিও আপনি বিল্ড ভেরিয়েন্টগুলি সরাসরি কনফিগার করেন না, আপনি বিল্ডের ধরন এবং পণ্যের স্বাদগুলি কনফিগার করেন যা তাদের গঠন করে।
উদাহরণস্বরূপ, একটি "ডেমো" পণ্যের স্বাদ নির্দিষ্ট বৈশিষ্ট্য এবং ডিভাইসের প্রয়োজনীয়তাগুলি নির্দিষ্ট করতে পারে, যেমন কাস্টম সোর্স কোড, সংস্থান এবং ন্যূনতম API স্তর, যখন "ডিবাগ" বিল্ড টাইপ বিভিন্ন বিল্ড এবং প্যাকেজিং সেটিংস প্রয়োগ করে, যেমন ডিবাগ বিকল্প এবং সাইনিং কী। বিল্ড ভেরিয়েন্ট যা এই দুটিকে একত্রিত করে তা হল আপনার অ্যাপের "ডেমোডিবাগ" সংস্করণ, এবং এতে "ডেমো" পণ্যের স্বাদ, "ডিবাগ" বিল্ড টাইপ এবং main/
উৎস সেটের অন্তর্ভুক্ত কনফিগারেশন এবং সংস্থানগুলির সংমিশ্রণ অন্তর্ভুক্ত রয়েছে।
বিল্ড প্রকারগুলি কনফিগার করুন
আপনি মডিউল-স্তরের build.gradle.kts
ফাইলের android
ব্লকের ভিতরে বিল্ড প্রকারগুলি তৈরি এবং কনফিগার করতে পারেন। আপনি যখন একটি নতুন মডিউল তৈরি করেন, তখন Android স্টুডিও স্বয়ংক্রিয়ভাবে ডিবাগ এবং রিলিজ বিল্ডের ধরন তৈরি করে। যদিও বিল্ড কনফিগারেশন ফাইলে ডিবাগ বিল্ড টাইপ প্রদর্শিত হয় না, তবে অ্যান্ড্রয়েড স্টুডিও এটিকে debuggable true
দিয়ে কনফিগার করে। এটি আপনাকে নিরাপদ অ্যান্ড্রয়েড ডিভাইসে অ্যাপটিকে ডিবাগ করতে দেয় এবং জেনেরিক ডিবাগ কীস্টোর দিয়ে অ্যাপ সাইনিং কনফিগার করতে দেয়।
আপনি যদি নির্দিষ্ট সেটিংস যোগ করতে বা পরিবর্তন করতে চান তবে আপনি আপনার কনফিগারেশনে ডিবাগ বিল্ড টাইপ যোগ করতে পারেন। নিচের নমুনাটি ডিবাগ বিল্ড টাইপের জন্য একটি applicationIdSuffix
নির্দিষ্ট করে এবং একটি "স্টেজিং" বিল্ড টাইপ কনফিগার করে যা ডিবাগ বিল্ড টাইপ থেকে সেটিংস ব্যবহার করে আরম্ভ করা হয়:
কোটলিন
android { defaultConfig { manifestPlaceholders["hostName"] = "www.example.com" ... } buildTypes { getByName("release") { isMinifyEnabled = true proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro") } getByName("debug") { applicationIdSuffix = ".debug" isDebuggable = true } /** * The `initWith` property lets you copy configurations from other build types, * then configure only the settings you want to change. This one copies the debug build * type, and then changes the manifest placeholder and application ID. */ create("staging") { initWith(getByName("debug")) manifestPlaceholders["hostName"] = "internal.example.com" applicationIdSuffix = ".debugStaging" } } }
গ্রোভি
android { defaultConfig { manifestPlaceholders = [hostName:"www.example.com"] ... } buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } debug { applicationIdSuffix ".debug" debuggable true } /** * The `initWith` property lets you copy configurations from other build types, * then configure only the settings you want to change. This one copies the debug build * type, and then changes the manifest placeholder and application ID. */ staging { initWith debug manifestPlaceholders = [hostName:"internal.example.com"] applicationIdSuffix ".debugStaging" } } }
দ্রষ্টব্য: আপনি যখন একটি বিল্ড কনফিগারেশন ফাইলে পরিবর্তন করেন, তখন Android স্টুডিওর প্রয়োজন হয় যে আপনি নতুন কনফিগারেশনের সাথে আপনার প্রকল্পটি সিঙ্ক করুন৷ আপনার প্রজেক্ট সিঙ্ক করতে, নোটিফিকেশন বারে Sync Now- এ ক্লিক করুন যা আপনি যখন কোনও পরিবর্তন করেন বা সিঙ্ক প্রজেক্টে ক্লিক করেন টুলবার থেকে। যদি অ্যান্ড্রয়েড স্টুডিও আপনার কনফিগারেশনে কোনো ত্রুটি লক্ষ্য করে, তাহলে বার্তা উইন্ডোটি সমস্যাটি বর্ণনা করতে দেখায়।
আপনি বিল্ড প্রকারের সাথে কনফিগার করতে পারেন এমন সমস্ত বৈশিষ্ট্য সম্পর্কে আরও জানতে, BuildType
রেফারেন্স পড়ুন।
পণ্যের স্বাদ কনফিগার করুন
পণ্যের স্বাদ তৈরি করা বিল্ড প্রকার তৈরির অনুরূপ। আপনার বিল্ড কনফিগারেশনে প্রোডাক্ট productFlavors
ব্লকে পণ্যের স্বাদ যোগ করুন এবং আপনি যে সেটিংস চান তা অন্তর্ভুক্ত করুন। পণ্যের স্বাদগুলি defaultConfig
মতো একই বৈশিষ্ট্যগুলিকে সমর্থন করে, কারণ defaultConfig
আসলে ProductFlavor
শ্রেণীর অন্তর্গত। এর মানে হল আপনি defaultConfig
ব্লকে সমস্ত স্বাদের জন্য বেস কনফিগারেশন প্রদান করতে পারেন, এবং প্রতিটি স্বাদ এই ডিফল্ট মানগুলির যেকোনো পরিবর্তন করতে পারে, যেমন applicationId
। অ্যাপ্লিকেশন আইডি সম্পর্কে আরও জানতে, অ্যাপ্লিকেশন আইডি সেট করুন পড়ুন।
দ্রষ্টব্য: আপনাকে এখনও main/
ম্যানিফেস্ট ফাইলে package
বৈশিষ্ট্য ব্যবহার করে একটি প্যাকেজের নাম উল্লেখ করতে হবে। R
শ্রেণীতে উল্লেখ করতে বা কোনো আপেক্ষিক কার্যকলাপ বা পরিষেবা নিবন্ধন সমাধানের জন্য আপনাকে অবশ্যই আপনার উত্স কোডে সেই প্যাকেজের নামটি ব্যবহার করতে হবে। এটি আপনাকে আপনার সোর্স কোড পরিবর্তন না করেই প্রতিটি পণ্যের স্বাদকে প্যাকেজিং এবং বিতরণের জন্য একটি অনন্য আইডি দিতে applicationId
ব্যবহার করতে দেয়।
সমস্ত স্বাদ অবশ্যই একটি নামযুক্ত স্বাদের মাত্রার অন্তর্গত হতে হবে, যা পণ্যের স্বাদের একটি গ্রুপ। আপনি একটি স্বাদ মাত্রা সব স্বাদ বরাদ্দ করা আবশ্যক; অন্যথায়, আপনি নিম্নলিখিত বিল্ড ত্রুটি পাবেন।
Error: All flavors must now belong to a named flavor dimension. The flavor 'flavor_name' is not assigned to a flavor dimension.
যদি একটি প্রদত্ত মডিউল শুধুমাত্র একটি স্বাদের মাত্রা নির্দিষ্ট করে, তাহলে Android Gradle প্লাগইন স্বয়ংক্রিয়ভাবে মডিউলের সমস্ত স্বাদকে সেই মাত্রায় বরাদ্দ করে।
নিম্নলিখিত কোড নমুনা "সংস্করণ" নামে একটি স্বাদের মাত্রা তৈরি করে এবং "ডেমো" এবং "সম্পূর্ণ" পণ্যের স্বাদ যোগ করে। এই স্বাদগুলি তাদের নিজস্ব applicationIdSuffix
এবং versionNameSuffix
প্রদান করে:
কোটলিন
android { ... defaultConfig {...} buildTypes { getByName("debug"){...} getByName("release"){...} } // Specifies one flavor dimension. flavorDimensions += "version" productFlavors { create("demo") { // Assigns this product flavor to the "version" flavor dimension. // If you are using only one dimension, this property is optional, // and the plugin automatically assigns all the module's flavors to // that dimension. dimension = "version" applicationIdSuffix = ".demo" versionNameSuffix = "-demo" } create("full") { dimension = "version" applicationIdSuffix = ".full" versionNameSuffix = "-full" } } }
গ্রোভি
android { ... defaultConfig {...} buildTypes { debug{...} release{...} } // Specifies one flavor dimension. flavorDimensions "version" productFlavors { demo { // Assigns this product flavor to the "version" flavor dimension. // If you are using only one dimension, this property is optional, // and the plugin automatically assigns all the module's flavors to // that dimension. dimension "version" applicationIdSuffix ".demo" versionNameSuffix "-demo" } full { dimension "version" applicationIdSuffix ".full" versionNameSuffix "-full" } } }
দ্রষ্টব্য: আপনার যদি একটি লিগ্যাসি অ্যাপ (আগস্ট 2021 সালের আগে তৈরি) থাকে যা আপনি Google Play-তে APK ব্যবহার করে বিতরণ করেন, Google Play-তে একাধিক APK সমর্থন ব্যবহার করে আপনার অ্যাপ বিতরণ করতে, সমস্ত ভেরিয়েন্টে একই applicationId
মান বরাদ্দ করুন এবং প্রতিটি ভেরিয়েন্টকে একটি ভিন্ন versionCode
দিন। আপনার অ্যাপের বিভিন্ন রূপকে Google Play-তে আলাদা অ্যাপ হিসেবে বিতরণ করতে, আপনাকে প্রতিটি ভেরিয়েন্টে একটি আলাদা applicationId
বরাদ্দ করতে হবে।
আপনি আপনার পণ্যের স্বাদগুলি তৈরি এবং কনফিগার করার পরে, বিজ্ঞপ্তি বারে এখন সিঙ্ক করুন ক্লিক করুন৷ একবার সিঙ্ক সম্পূর্ণ হলে, গ্রেডল স্বয়ংক্রিয়ভাবে আপনার বিল্ডের ধরন এবং পণ্যের স্বাদের উপর ভিত্তি করে বিল্ড ভেরিয়েন্ট তৈরি করে এবং <product-flavor><Build-Type>
অনুসারে তাদের নাম দেয়। উদাহরণস্বরূপ, আপনি যদি "ডেমো" এবং "সম্পূর্ণ" পণ্যের স্বাদ তৈরি করেন এবং ডিফল্ট "ডিবাগ" এবং "রিলিজ" বিল্ডের ধরন রাখেন, তাহলে Gradle নিম্নলিখিত বিল্ড ভেরিয়েন্টগুলি তৈরি করে:
-
demoDebug
-
demoRelease
-
fullDebug
-
fullRelease
কোন বিল্ড ভেরিয়েন্টটি তৈরি এবং চালানো হবে তা নির্বাচন করতে, বিল্ড > বিল্ড ভেরিয়েন্ট নির্বাচন করুন এবং মেনু থেকে একটি বিল্ড ভেরিয়েন্ট নির্বাচন করুন। প্রতিটি বিল্ড বৈকল্পিককে নিজস্ব বৈশিষ্ট্য এবং সংস্থানগুলির সাথে কাস্টমাইজ করা শুরু করতে, আপনাকে এই পৃষ্ঠায় বর্ণিত উত্স সেটগুলি তৈরি এবং পরিচালনা করতে হবে৷
বিল্ড ভেরিয়েন্টের জন্য অ্যাপ্লিকেশন আইডি পরিবর্তন করুন
আপনি যখন আপনার অ্যাপের জন্য একটি APK বা AAB তৈরি করেন, তখন বিল্ড টুলগুলি নিম্নলিখিত উদাহরণে দেখানো হয়েছে, build.gradle.kts
ফাইল থেকে defaultConfig
ব্লকে সংজ্ঞায়িত অ্যাপ্লিকেশন আইডি দিয়ে অ্যাপটিকে ট্যাগ করে। যাইহোক, যদি আপনি Google Play Store-এ "ফ্রি" এবং "প্রো" সংস্করণের মতো আলাদা তালিকা হিসাবে প্রদর্শিত হওয়ার জন্য আপনার অ্যাপের বিভিন্ন সংস্করণ তৈরি করতে চান, তাহলে আপনাকে আলাদা আলাদা বিল্ড ভেরিয়েন্ট তৈরি করতে হবে যার প্রত্যেকটির আলাদা অ্যাপ্লিকেশন আইডি আছে।
এই ক্ষেত্রে, প্রতিটি বিল্ড বৈকল্পিককে একটি পৃথক পণ্যের স্বাদ হিসাবে সংজ্ঞায়িত করুন। productFlavors
ব্লকের প্রতিটি স্বাদের জন্য, আপনি applicationId
বৈশিষ্ট্যটি পুনরায় সংজ্ঞায়িত করতে পারেন, অথবা আপনি applicationIdSuffix
ব্যবহার করে ডিফল্ট অ্যাপ্লিকেশন আইডিতে একটি সেগমেন্ট যুক্ত করতে পারেন, যেমনটি এখানে দেখানো হয়েছে:
কোটলিন
android { defaultConfig { applicationId = "com.example.myapp" } productFlavors { create("free") { applicationIdSuffix = ".free" } create("pro") { applicationIdSuffix = ".pro" } } }
গ্রোভি
android { defaultConfig { applicationId "com.example.myapp" } productFlavors { free { applicationIdSuffix ".free" } pro { applicationIdSuffix ".pro" } } }
এইভাবে, "ফ্রি" পণ্যের স্বাদের জন্য অ্যাপ্লিকেশন আইডি হল "com.example.myapp.free"৷
আপনি আপনার বিল্ড টাইপের উপর ভিত্তি করে একটি সেগমেন্ট যুক্ত করতে applicationIdSuffix
ব্যবহার করতে পারেন, যেমনটি এখানে দেখানো হয়েছে:
কোটলিন
android { ... buildTypes { getByName("debug") { applicationIdSuffix = ".debug" } } }
গ্রোভি
android { ... buildTypes { debug { applicationIdSuffix ".debug" } } }
যেহেতু Gradle প্রোডাক্ট ফ্লেভারের পরে বিল্ড টাইপ কনফিগারেশন প্রয়োগ করে, তাই "ফ্রি ডিবাগ" বিল্ড ভেরিয়েন্টের অ্যাপ্লিকেশন আইডি হল "com.example.myapp.free.debug"। আপনি যখন একই ডিভাইসে ডিবাগ এবং রিলিজ বিল্ড করতে চান তখন এটি কার্যকর, কারণ দুটি অ্যাপের একই অ্যাপ্লিকেশন আইডি থাকতে পারে না।
আপনার যদি একটি লিগ্যাসি অ্যাপ (আগস্ট 2021 সালের আগে তৈরি) থাকে যেটি আপনি Google Play-তে APK ব্যবহার করে বিতরণ করেন এবং আপনি একই অ্যাপ তালিকা ব্যবহার করে একাধিক APK বিতরণ করতে চান যেগুলি প্রতিটি আলাদা ডিভাইস কনফিগারেশনকে লক্ষ্য করে, যেমন API স্তর, তাহলে আপনাকে অবশ্যই প্রতিটি বিল্ড ভেরিয়েন্টের জন্য একই অ্যাপ্লিকেশন আইডি ব্যবহার করতে হবে তবে প্রতিটি APKকে একটি ভিন্নversionCode
দিতে হবে। আরও তথ্যের জন্য, একাধিক APK সমর্থন সম্পর্কে পড়ুন। AABs ব্যবহার করে প্রকাশনা প্রভাবিত হয় না, কারণ এটি একটি একক আর্টিফ্যাক্ট ব্যবহার করে যা ডিফল্টরূপে একটি একক সংস্করণ কোড এবং অ্যাপ্লিকেশন আইডি ব্যবহার করে। টিপ: আপনি যদি আপনার ম্যানিফেস্ট ফাইলে অ্যাপ্লিকেশন আইডি উল্লেখ করতে চান, আপনি যেকোনো ম্যানিফেস্ট অ্যাট্রিবিউটে ${applicationId}
প্লেসহোল্ডার ব্যবহার করতে পারেন। একটি বিল্ড করার সময়, Gradle এই ট্যাগটিকে প্রকৃত অ্যাপ্লিকেশন আইডি দিয়ে প্রতিস্থাপন করে। আরও তথ্যের জন্য, ম্যানিফেস্টে বিল্ড ভেরিয়েবল ইনজেক্ট করুন ।
গন্ধ মাত্রা সঙ্গে একাধিক পণ্য স্বাদ একত্রিত
কিছু ক্ষেত্রে, আপনি একাধিক পণ্যের স্বাদ থেকে কনফিগারেশন একত্রিত করতে চাইতে পারেন। উদাহরণস্বরূপ, আপনি API স্তরের উপর ভিত্তি করে "সম্পূর্ণ" এবং "ডেমো" পণ্যের স্বাদের জন্য বিভিন্ন কনফিগারেশন তৈরি করতে চাইতে পারেন। এটি করার জন্য, Android Gradle প্লাগইন আপনাকে স্বাদের মাত্রা হিসাবে পণ্যের স্বাদের একাধিক গ্রুপ তৈরি করতে দেয়।
আপনার অ্যাপ তৈরি করার সময়, গ্রেডল চূড়ান্ত বিল্ড বৈকল্পিক তৈরি করতে বিল্ড টাইপ কনফিগারেশনের সাথে আপনার সংজ্ঞায়িত প্রতিটি ফ্লেভার ডাইমেনশন থেকে একটি প্রোডাক্ট ফ্লেভার কনফিগারেশন একত্রিত করে। Gradle একই স্বাদের মাত্রার সাথে সম্পর্কিত পণ্যের স্বাদগুলিকে একত্রিত করে না।
নিম্নলিখিত কোড নমুনাটি API স্তরের উপর ভিত্তি করে "সম্পূর্ণ" এবং "ডেমো" পণ্যের স্বাদগুলিকে গোষ্ঠীভুক্ত করতে একটি "মোড" স্বাদের মাত্রা তৈরি করতে এবং একটি "এপিআই" ফ্লেভারের মাত্রা তৈরি করতে flavorDimensions
বৈশিষ্ট্য ব্যবহার করে:
কোটলিন
android { ... buildTypes { getByName("debug") {...} getByName("release") {...} } // Specifies the flavor dimensions you want to use. The order in which you // list the dimensions determines their priority, from highest to lowest, // when Gradle merges variant sources and configurations. You must assign // each product flavor you configure to one of the flavor dimensions. flavorDimensions += listOf("api", "mode") productFlavors { create("demo") { // Assigns this product flavor to the "mode" flavor dimension. dimension = "mode" ... } create("full") { dimension = "mode" ... } // Configurations in the "api" product flavors override those in "mode" // flavors and the defaultConfig block. Gradle determines the priority // between flavor dimensions based on the order in which they appear next // to the flavorDimensions property, with the first dimension having a higher // priority than the second, and so on. create("minApi24") { dimension = "api" minSdk = 24 // To ensure the target device receives the version of the app with // the highest compatible API level, assign version codes in increasing // value with API level. versionCode = 30000 + (android.defaultConfig.versionCode ?: 0) versionNameSuffix = "-minApi24" ... } create("minApi23") { dimension = "api" minSdk = 23 versionCode = 20000 + (android.defaultConfig.versionCode ?: 0) versionNameSuffix = "-minApi23" ... } create("minApi21") { dimension = "api" minSdk = 21 versionCode = 10000 + (android.defaultConfig.versionCode ?: 0) versionNameSuffix = "-minApi21" ... } } } ...
গ্রোভি
android { ... buildTypes { debug {...} release {...} } // Specifies the flavor dimensions you want to use. The order in which you // list the dimensions determines their priority, from highest to lowest, // when Gradle merges variant sources and configurations. You must assign // each product flavor you configure to one of the flavor dimensions. flavorDimensions "api", "mode" productFlavors { demo { // Assigns this product flavor to the "mode" flavor dimension. dimension "mode" ... } full { dimension "mode" ... } // Configurations in the "api" product flavors override those in "mode" // flavors and the defaultConfig block. Gradle determines the priority // between flavor dimensions based on the order in which they appear next // to the flavorDimensions property, with the first dimension having a higher // priority than the second, and so on. minApi24 { dimension "api" minSdkVersion 24 // To ensure the target device receives the version of the app with // the highest compatible API level, assign version codes in increasing // value with API level. versionCode 30000 + android.defaultConfig.versionCode versionNameSuffix "-minApi24" ... } minApi23 { dimension "api" minSdkVersion 23 versionCode 20000 + android.defaultConfig.versionCode versionNameSuffix "-minApi23" ... } minApi21 { dimension "api" minSdkVersion 21 versionCode 10000 + android.defaultConfig.versionCode versionNameSuffix "-minApi21" ... } } } ...
Gradle তৈরি করা বিল্ড ভেরিয়েন্টের সংখ্যা প্রতিটি ফ্লেভার ডাইমেনশনে ফ্লেভারের সংখ্যা এবং আপনার কনফিগার করা বিল্ড ধরনের সংখ্যার গুণফলের সমান। গ্রেডল যখন প্রতিটি বিল্ড ভেরিয়েন্ট বা সংশ্লিষ্ট শিল্পকর্মের নাম দেয়, তখন উচ্চ-অগ্রাধিকারের ফ্লেভার ডাইমেনশনের পণ্যের ফ্লেভারগুলি প্রথমে প্রদর্শিত হয়, তারপরে নিম্ন-অগ্রাধিকারের মাত্রাগুলি, তারপরে বিল্ডের ধরন দ্বারা অনুসরণ করা হয়।
একটি উদাহরণ হিসাবে পূর্ববর্তী বিল্ড কনফিগারেশন ব্যবহার করে, Gradle নিম্নলিখিত নামকরণ স্কিম সহ মোট 12টি বিল্ড ভেরিয়েন্ট তৈরি করে:
- বিল্ড ভেরিয়েন্ট:
[minApi24, minApi23, minApi21][Demo, Full][Debug, Release]
- সংশ্লিষ্ট APK:
app-[minApi24, minApi23, minApi21]-[demo, full]-[debug, release].apk
- যেমন,
- বিল্ড ভেরিয়েন্ট:
minApi24DemoDebug
- সংশ্লিষ্ট APK:
app-minApi24-demo-debug.apk
সোর্স সেট ডিরেক্টরিগুলি ছাড়াও আপনি প্রতিটি পণ্যের স্বাদের জন্য তৈরি করতে পারেন এবং বৈকল্পিক তৈরি করতে পারেন, আপনি পণ্যের স্বাদের প্রতিটি সংমিশ্রণের জন্য উত্স সেট ডিরেক্টরিও তৈরি করতে পারেন। উদাহরণস্বরূপ, আপনি src/demoMinApi24/java/
ডিরেক্টরিতে জাভা উত্সগুলি তৈরি করতে এবং যোগ করতে পারেন, এবং গ্রেডল শুধুমাত্র সেই উত্সগুলি ব্যবহার করে যখন একটি ভেরিয়েন্ট তৈরি করে যা এই দুটি পণ্যের স্বাদকে একত্রিত করে।
প্রোডাক্ট ফ্লেভার কম্বিনেশনের জন্য আপনি যে সোর্স সেটগুলি তৈরি করেন সেগুলি প্রতিটি আলাদা প্রোডাক্ট ফ্লেভারের সোর্স সেটগুলির থেকে বেশি অগ্রাধিকার পায়৷ সোর্স সেট সম্পর্কে আরও জানতে এবং গ্রেডল কীভাবে সংস্থানগুলিকে একত্রিত করে, কীভাবে উত্স সেট তৈরি করতে হয় সে সম্পর্কে বিভাগটি পড়ুন।
ফিল্টার বৈকল্পিক
Gradle আপনার কনফিগার করা পণ্যের স্বাদ এবং বিল্ড প্রকারের প্রতিটি সম্ভাব্য সমন্বয়ের জন্য একটি বিল্ড বৈকল্পিক তৈরি করে। যাইহোক, কিছু বিল্ড ভেরিয়েন্ট থাকতে পারে যা আপনার প্রয়োজন নেই বা আপনার প্রজেক্টের প্রেক্ষাপটে অর্থপূর্ণ নয়। নির্দিষ্ট বিল্ড বৈকল্পিক কনফিগারেশন অপসারণ করতে, আপনার মডিউল-স্তরের build.gradle.kts
ফাইলে একটি বৈকল্পিক ফিল্টার তৈরি করুন।
উদাহরণ হিসাবে পূর্ববর্তী বিভাগ থেকে বিল্ড কনফিগারেশন ব্যবহার করে, ধরুন আপনি অ্যাপের ডেমো সংস্করণের জন্য শুধুমাত্র API স্তর 23 এবং উচ্চতর সমর্থন করার পরিকল্পনা করছেন। আপনি "minApi21" এবং "ডেমো" পণ্যের স্বাদকে একত্রিত করে এমন সমস্ত বিল্ড বৈকল্পিক কনফিগারেশন ফিল্টার করতে variantFilter
ব্লক ব্যবহার করতে পারেন:
কোটলিন
android { ... buildTypes {...} flavorDimensions += listOf("api", "mode") productFlavors { create("demo") {...} create("full") {...} create("minApi24") {...} create("minApi23") {...} create("minApi21") {...} } } androidComponents { beforeVariants { variantBuilder -> // To check for a certain build type, use variantBuilder.buildType == "<buildType>" if (variantBuilder.productFlavors.containsAll(listOf("api" to "minApi21", "mode" to "demo"))) { // Gradle ignores any variants that satisfy the conditions above. variantBuilder.enable = false } } } ...
গ্রোভি
android { ... buildTypes {...} flavorDimensions "api", "mode" productFlavors { demo {...} full {...} minApi24 {...} minApi23 {...} minApi21 {...} } variantFilter { variant -> def names = variant.flavors*.name // To check for a certain build type, use variant.buildType.name == "<buildType>" if (names.contains("minApi21") && names.contains("demo")) { // Gradle ignores any variants that satisfy the conditions above. setIgnore(true) } } } ...
একবার আপনি আপনার বিল্ড কনফিগারেশনে একটি বৈকল্পিক ফিল্টার যোগ করলে এবং বিজ্ঞপ্তি বারে এখন সিঙ্ক করুন ক্লিক করুন, Gradle আপনার নির্দিষ্ট শর্ত পূরণ করে এমন কোনো বিল্ড ভেরিয়েন্টকে উপেক্ষা করে। বিল্ড ভেরিয়েন্টগুলি আর মেনুতে উপস্থিত হয় না যখন আপনি বিল্ড > মেনু বার থেকে বিল্ড ভেরিয়েন্ট বা বিল্ড ভেরিয়েন্টে ক্লিক করেন টুল উইন্ডো বারে।
সোর্স সেট তৈরি করুন
ডিফল্টরূপে, অ্যান্ড্রয়েড স্টুডিও আপনার সমস্ত বিল্ড ভেরিয়েন্টের মধ্যে শেয়ার করতে চান এমন সবকিছুর জন্য main/
উৎস সেট এবং ডিরেক্টরি তৈরি করে। যাইহোক, আপনি ঠিক কোন ফাইলগুলি Gradle কম্পাইল করে এবং নির্দিষ্ট বিল্ডের ধরন, পণ্যের স্বাদ, পণ্যের স্বাদের সংমিশ্রণ ( গন্ধের মাত্রা ব্যবহার করার সময়) এবং বিল্ড ভেরিয়েন্টগুলির জন্য প্যাকেজগুলি ঠিক করে তা নিয়ন্ত্রণ করতে আপনি নতুন উত্স সেট তৈরি করতে পারেন।
উদাহরণস্বরূপ, আপনি main/
উৎস সেটে মৌলিক কার্যকারিতা নির্ধারণ করতে পারেন এবং বিভিন্ন ক্লায়েন্টের জন্য আপনার অ্যাপের ব্র্যান্ডিং পরিবর্তন করতে পণ্যের স্বাদের উৎস সেট ব্যবহার করতে পারেন, অথবা শুধুমাত্র ডিবাগ বিল্ড টাইপ ব্যবহার করে এমন বিল্ড ভেরিয়েন্টের জন্য বিশেষ অনুমতি এবং লগিং কার্যকারিতা অন্তর্ভুক্ত করতে পারেন।
গ্রেডল আশা করে যে উত্স সেট ফাইল এবং ডিরেক্টরিগুলি একটি নির্দিষ্ট উপায়ে সংগঠিত হবে, main/
উত্স সেটের অনুরূপ। উদাহরণস্বরূপ, গ্রেডল আশা করে যে কোটলিন বা জাভা ক্লাস ফাইলগুলি যেগুলি আপনার "ডিবাগ" বিল্ড টাইপের জন্য নির্দিষ্ট সেগুলি src/debug/kotlin/
বা src/debug/java/
ডিরেক্টরিতে অবস্থিত।
অ্যান্ড্রয়েড গ্রেডল প্লাগইন একটি দরকারী গ্রেডল টাস্ক সরবরাহ করে যা আপনাকে দেখায় কিভাবে আপনার প্রতিটি বিল্ড প্রকার, পণ্যের স্বাদ এবং বিল্ড ভেরিয়েন্টের জন্য আপনার ফাইলগুলিকে সংগঠিত করতে হয়। উদাহরণস্বরূপ, টাস্ক আউটপুট থেকে নিম্নলিখিত নমুনা বর্ণনা করে যেখানে গ্রেডল "ডিবাগ" বিল্ড টাইপের জন্য নির্দিষ্ট ফাইলগুলি খুঁজে পাওয়ার আশা করে:
------------------------------------------------------------ Project :app ------------------------------------------------------------ ... debug ---- Compile configuration: debugCompile build.gradle name: android.sourceSets.debug Java sources: [app/src/debug/java] Kotlin sources: [app/src/debug/kotlin, app/src/debug/java] Manifest file: app/src/debug/AndroidManifest.xml Android resources: [app/src/debug/res] Assets: [app/src/debug/assets] AIDL sources: [app/src/debug/aidl] RenderScript sources: [app/src/debug/rs] JNI sources: [app/src/debug/jni] JNI libraries: [app/src/debug/jniLibs] Java-style resources: [app/src/debug/resources]
এই আউটপুট দেখতে, নিম্নলিখিত হিসাবে এগিয়ে যান:
- টুল উইন্ডো বারে Gradle ক্লিক করুন।
MyApplication > Tasks > android- এ নেভিগেট করুন এবং sourceSets-এ ডাবল-ক্লিক করুন।
টাস্ক ফোল্ডার দেখতে, আপনাকে অবশ্যই গ্র্যাডলকে সিঙ্কের সময় টাস্ক তালিকা তৈরি করতে দিতে হবে। এটি করতে, এই পদক্ষেপগুলি অনুসরণ করুন:
- ফাইল > সেটিংস > পরীক্ষামূলক ( অ্যান্ড্রয়েড স্টুডিও > সেটিংস > ম্যাকওএসে পরীক্ষামূলক ) ক্লিক করুন।
- Gradle সিঙ্কের সময় Gradle টাস্ক লিস্ট তৈরি করবেন না তা অনির্বাচন করুন।
- Gradle টাস্কটি কার্যকর করার পরে, রান উইন্ডোটি আউটপুট প্রদর্শনের জন্য খোলে।
দ্রষ্টব্য: টাস্ক আউটপুট আপনাকে দেখায় কিভাবে আপনি আপনার অ্যাপের জন্য পরীক্ষা চালানোর জন্য যে ফাইলগুলি ব্যবহার করতে চান তার জন্য সোর্স সেটগুলি সংগঠিত করবেন, যেমন test/
এবং androidTest/
টেস্টিং সোর্স সেট ৷
আপনি যখন একটি নতুন বিল্ড ভেরিয়েন্ট তৈরি করেন, তখন অ্যান্ড্রয়েড স্টুডিও আপনার জন্য সোর্স সেট ডিরেক্টরি তৈরি করে না, তবে এটি আপনাকে সাহায্য করার জন্য কয়েকটি বিকল্প দেয়। উদাহরণস্বরূপ, আপনার "ডিবাগ" বিল্ড টাইপের জন্য java/
ডিরেক্টরি তৈরি করতে:
- প্রকল্প ফলকটি খুলুন এবং ফলকের শীর্ষে থাকা মেনু থেকে প্রকল্প দৃশ্যটি নির্বাচন করুন।
-
MyProject/app/src/
এ নেভিগেট করুন। -
src
ডিরেক্টরিতে ডান-ক্লিক করুন এবং নতুন > ডিরেক্টরি নির্বাচন করুন। - গ্রেডল সোর্স সেটের অধীনে মেনু থেকে, ফুল/জাভা নির্বাচন করুন।
- এন্টার টিপুন।
অ্যান্ড্রয়েড স্টুডিও আপনার ডিবাগ বিল্ড টাইপের জন্য একটি সোর্স সেট ডিরেক্টরি তৈরি করে এবং তারপর এটির ভিতরে java/
ডিরেক্টরি তৈরি করে। বিকল্পভাবে, যখন আপনি একটি নির্দিষ্ট বিল্ড ভেরিয়েন্টের জন্য আপনার প্রকল্পে একটি নতুন ফাইল যোগ করেন তখন Android স্টুডিও আপনার জন্য ডিরেক্টরি তৈরি করতে পারে।
উদাহরণস্বরূপ, আপনার "ডিবাগ" বিল্ড টাইপের জন্য একটি মান XML ফাইল তৈরি করতে:
- প্রকল্প ফলকে,
src
ডিরেক্টরিতে ডান-ক্লিক করুন এবং নতুন > XML > মান XML ফাইল নির্বাচন করুন। - XML ফাইলের নাম লিখুন বা ডিফল্ট নাম রাখুন।
- টার্গেট সোর্স সেটের পাশের মেনু থেকে, ডিবাগ নির্বাচন করুন।
- শেষ ক্লিক করুন.
যেহেতু "ডিবাগ" বিল্ড টাইপ টার্গেট সোর্স সেট হিসাবে নির্দিষ্ট করা হয়েছিল, Android স্টুডিও যখন XML ফাইল তৈরি করে তখন স্বয়ংক্রিয়ভাবে প্রয়োজনীয় ডিরেক্টরি তৈরি করে৷ ফলস্বরূপ ডিরেক্টরি গঠন চিত্র 1 এর মত দেখাচ্ছে।

চিত্র 1. "ডিবাগ" বিল্ড টাইপের জন্য নতুন উৎস সেট ডিরেক্টরি।
অ্যাক্টিভ সোর্স সেটের আইকনে একটি সবুজ সূচক থাকে যাতে তারা সক্রিয় তা দেখায়। debug
সোর্স সেটটি [main]
এর সাথে প্রত্যয়িত হয় তা দেখাতে যে এটি main
উৎস সেটে একত্রিত হবে।
একই পদ্ধতি ব্যবহার করে, আপনি পণ্যের স্বাদের জন্য সোর্স সেট ডিরেক্টরিও তৈরি করতে পারেন, যেমন src/demo/
, এবং src/demoDebug/
এর মতো ভেরিয়েন্ট তৈরি করতে পারেন। অতিরিক্তভাবে, আপনি টেস্টিং সোর্স সেট তৈরি করতে পারেন যা নির্দিষ্ট বিল্ড ভেরিয়েন্টকে লক্ষ্য করে, যেমন src/androidTestDemoDebug/
। আরও জানতে, উৎস সেট পরীক্ষা করা সম্পর্কে পড়ুন।
ডিফল্ট সোর্স সেট কনফিগারেশন পরিবর্তন করুন
যদি আপনার কাছে এমন উত্স থাকে যা গ্র্যাডল আশা করে যে ডিফল্ট সোর্স সেট ফাইল কাঠামোতে সংগঠিত না হয়, যেমন সোর্স সেট তৈরির বিষয়ে পূর্ববর্তী বিভাগে বর্ণিত হয়েছে, আপনি সোর্স সেটের প্রতিটি উপাদানের জন্য গ্রেডল যেখানে ফাইল সংগ্রহ করতে দেখায় তা পরিবর্তন করতে sourceSets
ব্লক ব্যবহার করতে পারেন।
sourceSets
ব্লক অবশ্যই android
ব্লকে থাকতে হবে। আপনাকে সোর্স ফাইলগুলিকে স্থানান্তর করতে হবে না; আপনাকে শুধুমাত্র মডিউল-স্তরের build.gradle.kts
ফাইলের সাপেক্ষে পাথ(গুলি) সহ Gradle প্রদান করতে হবে, যেখানে Gradle প্রতিটি সোর্স সেট কম্পোনেন্টের জন্য ফাইল খুঁজে পেতে পারে। আপনি কোন উপাদানগুলি কনফিগার করতে পারেন এবং আপনি সেগুলিকে একাধিক ফাইল বা ডিরেক্টরিতে ম্যাপ করতে পারেন কিনা তা জানতে, Android Gradle প্লাগইন API রেফারেন্স দেখুন।
নিম্নলিখিত কোড নমুনাটি app/other/
ডিরেক্টরি থেকে উত্সগুলিকে main
উত্স সেটের নির্দিষ্ট উপাদানগুলিতে ম্যাপ করে এবং androidTest
উত্স সেটের রুট ডিরেক্টরি পরিবর্তন করে:
কোটলিন
android { ... // Encapsulates configurations for the main source set. sourceSets.getByName("main") { // Changes the directory for Java sources. The default directory is // 'src/main/java'. java.setSrcDirs(listOf("other/java")) // If you list multiple directories, Gradle uses all of them to collect // sources. Because Gradle gives these directories equal priority, if // you define the same resource in more than one directory, you receive an // error when merging resources. The default directory is 'src/main/res'. res.setSrcDirs(listOf("other/res1", "other/res2")) // Note: Avoid specifying a directory that is a parent to one // or more other directories you specify. For example, avoid the following: // res.srcDirs = ['other/res1', 'other/res1/layouts', 'other/res1/strings'] // Specify either only the root 'other/res1' directory or only the // nested 'other/res1/layouts' and 'other/res1/strings' directories. // For each source set, you can specify only one Android manifest. // By default, Android Studio creates a manifest for your main source // set in the src/main/ directory. manifest.srcFile("other/AndroidManifest.xml") ... } // Create additional blocks to configure other source sets. sourceSets.getByName("androidTest") { // If all the files for a source set are located under a single root // directory, you can specify that directory using the setRoot property. // When gathering sources for the source set, Gradle looks only in locations // relative to the root directory you specify. For example, after applying the // configuration below for the androidTest source set, Gradle looks for Java // sources only in the src/tests/java/ directory. setRoot("src/tests") ... } } ...
গ্রোভি
android { ... sourceSets { // Encapsulates configurations for the main source set. main { // Changes the directory for Java sources. The default directory is // 'src/main/java'. java.srcDirs = ['other/java'] // If you list multiple directories, Gradle uses all of them to collect // sources. Because Gradle gives these directories equal priority, if // you define the same resource in more than one directory, you receive an // error when merging resources. The default directory is 'src/main/res'. res.srcDirs = ['other/res1', 'other/res2'] // Note: Avoid specifying a directory that is a parent to one // or more other directories you specify. For example, avoid the following: // res.srcDirs = ['other/res1', 'other/res1/layouts', 'other/res1/strings'] // Specify either only the root 'other/res1' directory or only the // nested 'other/res1/layouts' and 'other/res1/strings' directories. // For each source set, you can specify only one Android manifest. // By default, Android Studio creates a manifest for your main source // set in the src/main/ directory. manifest.srcFile 'other/AndroidManifest.xml' ... } // Create additional blocks to configure other source sets. androidTest { // If all the files for a source set are located under a single root // directory, you can specify that directory using the setRoot property. // When gathering sources for the source set, Gradle looks only in locations // relative to the root directory you specify. For example, after applying the // configuration below for the androidTest source set, Gradle looks for Java // sources only in the src/tests/java/ directory. setRoot 'src/tests' ... } } } ...
মনে রাখবেন যে একটি উৎস ডিরেক্টরি শুধুমাত্র একটি উৎস সেটের অন্তর্গত হতে পারে। উদাহরণস্বরূপ, আপনি test
এবং androidTest
উত্স সেট উভয়ের সাথে একই পরীক্ষার উত্স ভাগ করতে পারবেন না৷ কারণ অ্যান্ড্রয়েড স্টুডিও প্রতিটি সোর্স সেটের জন্য আলাদা ইন্টেলিজে মডিউল তৈরি করে এবং সোর্স সেট জুড়ে ডুপ্লিকেট কন্টেন্ট রুট সমর্থন করতে পারে না।
সোর্স সেট দিয়ে তৈরি করুন
আপনি শুধুমাত্র নির্দিষ্ট কনফিগারেশনের সাথে প্যাকেজ করতে চান এমন কোড এবং সংস্থানগুলি ধারণ করতে উত্স সেট ডিরেক্টরি ব্যবহার করতে পারেন। উদাহরণস্বরূপ, আপনি যদি "demoDebug" বিল্ড ভেরিয়েন্ট তৈরি করছেন, যা একটি "ডেমো" পণ্যের স্বাদ এবং "ডিবাগ" বিল্ড টাইপের ক্রসপ্রোডাক্ট, গ্র্যাডল এই ডিরেক্টরিগুলি দেখে এবং সেগুলিকে নিম্নলিখিত অগ্রাধিকার দেয়:
-
src/demoDebug/
(ভেরিয়েন্ট সোর্স সেট তৈরি করুন) -
src/debug/
(বিল্ড টাইপ সোর্স সেট) -
src/demo/
(পণ্যের স্বাদ উৎস সেট) -
src/main/
(প্রধান উৎস সেট)
প্রোডাক্ট ফ্লেভারের সংমিশ্রণের জন্য তৈরি সোর্স সেটগুলিতে অবশ্যই সমস্ত স্বাদের মাত্রা অন্তর্ভুক্ত থাকতে হবে। উদাহরণস্বরূপ, বিল্ড ভেরিয়েন্ট সোর্স সেটটি অবশ্যই বিল্ড টাইপ এবং সমস্ত স্বাদের মাত্রার সমন্বয় হতে হবে। একাধিক কিন্তু সমস্ত স্বাদের মাত্রা নয় এমন ফোল্ডারের সাথে যুক্ত কোড এবং সংস্থানগুলি একত্রিত করা সমর্থিত নয়৷
আপনি যদি একাধিক পণ্যের স্বাদ একত্রিত করেন , তাহলে পণ্যের স্বাদের মধ্যে অগ্রাধিকার তারা যে স্বাদের মাত্রার সাথে সম্পর্কিত তা দ্বারা নির্ধারিত হয়। android.flavorDimensions
প্রপার্টির সাথে ফ্লেভার ডাইমেনশন তালিকাভুক্ত করার সময়, আপনার তালিকাভুক্ত প্রথম ফ্লেভার ডাইমেনশনের সাথে যুক্ত প্রোডাক্ট ফ্লেভারগুলি দ্বিতীয় ফ্লেভার ডাইমেনশনের তুলনায় বেশি অগ্রাধিকার পায় এবং আরও অনেক কিছু। অতিরিক্তভাবে, পণ্যের স্বাদের সংমিশ্রণের জন্য আপনি যে উত্স সেটগুলি তৈরি করেন সেগুলি একটি পৃথক পণ্যের স্বাদের উত্স সেটগুলির চেয়ে বেশি অগ্রাধিকার পায়৷
অগ্রাধিকার ক্রম নির্ধারণ করে যে কোন উৎস সেটে উচ্চতর অগ্রাধিকার রয়েছে যখন Gradle কোড এবং সংস্থানগুলিকে একত্রিত করে। কারণ demoDebug/
উৎস সেট ডিরেক্টরিতে সম্ভবত সেই বিল্ড ভেরিয়েন্টের জন্য নির্দিষ্ট ফাইল রয়েছে, যদি demoDebug/
একটি ফাইল অন্তর্ভুক্ত করে যা debug/
এও সংজ্ঞায়িত করা হয়, Gradle ফাইলটিকে demoDebug/
উৎস সেটে ব্যবহার করে। একইভাবে, গ্রেডল বিল্ড টাইপের ফাইল দেয় এবং প্রোডাক্ট ফ্লেভার সোর্স main/
এ একই ফাইলের তুলনায় উচ্চ অগ্রাধিকার সেট করে। নিম্নলিখিত বিল্ড নিয়মগুলি প্রয়োগ করার সময় Gradle এই অগ্রাধিকার আদেশটি বিবেচনা করে:
-
kotlin/
বাjava/
ডিরেক্টরির সমস্ত সোর্স কোড একটি একক আউটপুট তৈরি করতে একসাথে কম্পাইল করা হয়।দ্রষ্টব্য: একটি প্রদত্ত বিল্ড ভেরিয়েন্টের জন্য, Gradle একটি বিল্ড ত্রুটি নিক্ষেপ করে যদি এটি একই Kotlin বা Java ক্লাস সংজ্ঞায়িত করে এমন দুটি বা ততোধিক উৎস সেট ডিরেক্টরির সম্মুখীন হয়। উদাহরণস্বরূপ, একটি ডিবাগ অ্যাপ তৈরি করার সময়, আপনি
src/debug/Utility.kt
এবংsrc/main/Utility.kt
উভয়কেই সংজ্ঞায়িত করতে পারবেন না, কারণ বিল্ড প্রক্রিয়া চলাকালীন গ্রেডল এই দুটি ডিরেক্টরিই দেখে এবং একটি "ডুপ্লিকেট ক্লাস" ত্রুটি নিক্ষেপ করে৷ আপনি যদি বিভিন্ন ধরনের বিল্ডের জন্যUtility.kt
এর বিভিন্ন সংস্করণ চান, প্রতিটি বিল্ড টাইপকে অবশ্যই ফাইলের নিজস্ব সংস্করণ সংজ্ঞায়িত করতে হবে এবং এটিকেmain/
উৎস সেটে অন্তর্ভুক্ত করতে হবে না। - ম্যানিফেস্টগুলিকে একক ম্যানিফেস্টে একত্রিত করা হয়৷ অগ্রাধিকার পূর্ববর্তী উদাহরণে তালিকা হিসাবে একই ক্রমে দেওয়া হয়. অর্থাৎ, একটি বিল্ড টাইপের জন্য ম্যানিফেস্ট সেটিংস একটি পণ্যের স্বাদের জন্য ম্যানিফেস্ট সেটিংসকে ওভাররাইড করে, ইত্যাদি। আরও জানতে, ম্যানিফেস্ট মার্জিং সম্পর্কে পড়ুন।
-
values/
ডিরেক্টরির ফাইলগুলিকে একত্রিত করা হয়। যদি দুটি ফাইলের একই নাম থাকে, যেমন দুটিstrings.xml
ফাইল, অগ্রাধিকার পূর্ববর্তী উদাহরণে তালিকার মতো একই ক্রমে দেওয়া হয়। অর্থাৎ, বিল্ড টাইপ সোর্স সেটের একটি ফাইলে সংজ্ঞায়িত মানগুলি পণ্যের স্বাদে একই ফাইলে সংজ্ঞায়িত মানগুলিকে ওভাররাইড করে এবং আরও অনেক কিছু। -
res/
এবংasset/
ডিরেক্টরীতে সম্পদ একসাথে প্যাকেজ করা হয়। যদি দুই বা ততোধিক উৎস সেটে একই নামে সংজ্ঞায়িত সম্পদ থাকে, তাহলে অগ্রাধিকার পূর্ববর্তী উদাহরণে তালিকার মতো একই ক্রমে দেওয়া হয়। - Gradle অ্যাপ তৈরি করার সময় লাইব্রেরি মডিউল নির্ভরতার সাথে অন্তর্ভুক্ত সংস্থান এবং ম্যানিফেস্টগুলিকে সর্বনিম্ন অগ্রাধিকার দেয়।
নির্ভরতা ঘোষণা করুন
একটি নির্দিষ্ট বিল্ড ভেরিয়েন্ট বা টেস্টিং সোর্স সেটের জন্য নির্ভরতা কনফিগার করতে, Implementation
কীওয়ার্ডের আগে বিল্ড ভেরিয়েন্ট বা টেস্টিং সোর্স সেটের নাম প্রিফিক্স করুন, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে:
কোটলিন
dependencies { // Adds the local "mylibrary" module as a dependency to the "free" flavor. "freeImplementation"(project(":mylibrary")) // Adds a remote binary dependency only for local tests. testImplementation("junit:junit:4.12") // Adds a remote binary dependency only for the instrumented test APK. androidTestImplementation("com.android.support.test.espresso:espresso-core:3.6.1") }
গ্রোভি
dependencies { // Adds the local "mylibrary" module as a dependency to the "free" flavor. freeImplementation project(":mylibrary") // Adds a remote binary dependency only for local tests. testImplementation 'junit:junit:4.12' // Adds a remote binary dependency only for the instrumented test APK. androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.6.1' }
নির্ভরতা কনফিগার করার বিষয়ে আরও তথ্যের জন্য, বিল্ড নির্ভরতা যুক্ত করুন দেখুন।
বৈকল্পিক-সচেতন নির্ভরতা ব্যবস্থাপনা ব্যবহার করুন
অ্যান্ড্রয়েড গ্রেডল প্লাগইন 3.0.0 এবং উচ্চতর একটি নতুন নির্ভরতা প্রক্রিয়া অন্তর্ভুক্ত করে যা একটি লাইব্রেরি ব্যবহার করার সময় স্বয়ংক্রিয়ভাবে ভেরিয়েন্টের সাথে মেলে। এর মানে হল একটি অ্যাপের debug
ভেরিয়েন্ট স্বয়ংক্রিয়ভাবে একটি লাইব্রেরির debug
ভেরিয়েন্ট ব্যবহার করে, ইত্যাদি। এটি স্বাদগুলি ব্যবহার করার সময়ও কাজ করে: একটি অ্যাপের freeDebug
ভেরিয়েন্ট একটি লাইব্রেরির freeDebug
বৈকল্পিক গ্রাস করবে।
প্লাগইনটি সঠিকভাবে বৈকল্পিকগুলির সাথে মেলানোর জন্য, আপনাকে নিম্নলিখিত বিভাগে বর্ণিত মিলযুক্ত ফলব্যাকগুলি প্রদান করতে হবে, যেখানে সরাসরি মিল সম্ভব নয়।
উদাহরণস্বরূপ, ধরুন আপনার অ্যাপটি "স্টেজিং" নামক একটি বিল্ড টাইপ কনফিগার করে, কিন্তু এর একটি লাইব্রেরি নির্ভরতা তা করে না। যখন প্লাগইনটি আপনার অ্যাপের "স্টেজিং" সংস্করণ তৈরি করার চেষ্টা করে, তখন এটি লাইব্রেরির কোন সংস্করণটি ব্যবহার করতে হবে তা জানবে না এবং আপনি নিম্নলিখিতগুলির মতো একটি ত্রুটি বার্তা দেখতে পাবেন:
Error:Failed to resolve: Could not resolve project :mylibrary. Required by: project :app
বৈকল্পিক মিলের সাথে সম্পর্কিত বিল্ড ত্রুটিগুলি সমাধান করুন
প্লাগইনটিতে ডিএসএল উপাদান রয়েছে যাতে আপনি নিয়ন্ত্রণ করতে সাহায্য করেন যে কীভাবে গ্রেডল এমন পরিস্থিতিতে সমাধান করে যেখানে একটি অ্যাপ এবং নির্ভরতার মধ্যে সরাসরি বৈকল্পিক মিল সম্ভব নয়।
নিম্নে ভেরিয়েন্ট-সচেতন নির্ভরতা ম্যাচিং সম্পর্কিত সমস্যাগুলির একটি তালিকা এবং ডিএসএল বৈশিষ্ট্যগুলি ব্যবহার করে কীভাবে সেগুলি সমাধান করা যায়:আপনার অ্যাপটিতে একটি বিল্ড টাইপ রয়েছে যা একটি লাইব্রেরি নির্ভরতা করে না।
উদাহরণ স্বরূপ, আপনার অ্যাপে একটি "স্টেজিং" বিল্ড টাইপ রয়েছে, কিন্তু একটি নির্ভরতা শুধুমাত্র "ডিবাগ" এবং "রিলিজ" বিল্ড টাইপ অন্তর্ভুক্ত করে।
মনে রাখবেন যে যখন একটি লাইব্রেরি নির্ভরতা একটি বিল্ড টাইপ অন্তর্ভুক্ত করে যেটি আপনার অ্যাপে নেই তখন কোনো সমস্যা নেই। কারণ প্লাগইন কখনই নির্ভরতা থেকে বিল্ড টাইপের অনুরোধ করে না।
একটি প্রদত্ত বিল্ড টাইপের জন্য বিকল্প মিলগুলি নির্দিষ্ট করতে
matchingFallbacks
ব্যবহার করুন, যেমনটি এখানে দেখানো হয়েছে:কোটলিন
// In the app's build.gradle.kts file. android { buildTypes { getByName("debug") {} getByName("release") {} create("staging") { // Specifies a sorted list of fallback build types that the // plugin can try to use when a dependency does not include a // "staging" build type. You may specify as many fallbacks as you // like, and the plugin selects the first build type that's // available in the dependency. matchingFallbacks += listOf("debug", "qa", "release") } } }
গ্রোভি
// In the app's build.gradle file. android { buildTypes { debug {} release {} staging { // Specifies a sorted list of fallback build types that the // plugin can try to use when a dependency does not include a // "staging" build type. You may specify as many fallbacks as you // like, and the plugin selects the first build type that's // available in the dependency. matchingFallbacks = ['debug', 'qa', 'release'] } } }
একটি প্রদত্ত ফ্লেভার ডাইমেনশনের জন্য যা অ্যাপ এবং এর লাইব্রেরি নির্ভরতা উভয়েই বিদ্যমান, আপনার অ্যাপে এমন স্বাদ অন্তর্ভুক্ত রয়েছে যা লাইব্রেরিতে নেই।
উদাহরণস্বরূপ, আপনার অ্যাপ এবং এর লাইব্রেরি নির্ভরতা উভয়ই একটি "স্তরের" স্বাদের মাত্রা অন্তর্ভুক্ত করে। যাইহোক, অ্যাপের "স্তর" মাত্রায় "ফ্রি" এবং "পেইড" ফ্লেভার রয়েছে, কিন্তু একটি নির্ভরতা একই মাত্রার জন্য শুধুমাত্র "ডেমো" এবং "পেইড" ফ্লেভার অন্তর্ভুক্ত করে।
মনে রাখবেন যে একটি প্রদত্ত ফ্লেভার ডাইমেনশনের জন্য যা অ্যাপ এবং এর লাইব্রেরি নির্ভরতা উভয়েই বিদ্যমান, যখন একটি লাইব্রেরিতে এমন একটি পণ্যের স্বাদ অন্তর্ভুক্ত থাকে যা আপনার অ্যাপে নেই তখন কোনো সমস্যা নেই। কারণ প্লাগইন কখনই নির্ভরতা থেকে সেই স্বাদের জন্য অনুরোধ করে না।
অ্যাপের "ফ্রি" পণ্যের স্বাদের জন্য বিকল্প মিলগুলি নির্দিষ্ট করতে
matchingFallbacks
ব্যবহার করুন, যেমনটি এখানে দেখানো হয়েছে:কোটলিন
// In the app's build.gradle.kts file. android { defaultConfig{ // Don't configure matchingFallbacks in the defaultConfig block. // Instead, specify fallbacks for a given product flavor in the // productFlavors block, as shown below. } flavorDimensions += "tier" productFlavors { create("paid") { dimension = "tier" // Because the dependency already includes a "paid" flavor in its // "tier" dimension, you don't need to provide a list of fallbacks // for the "paid" flavor. } create("free") { dimension = "tier" // Specifies a sorted list of fallback flavors that the plugin // can try to use when a dependency's matching dimension does // not include a "free" flavor. Specify as many // fallbacks as you like; the plugin selects the first flavor // that's available in the dependency's "tier" dimension. matchingFallbacks += listOf("demo", "trial") } } }
গ্রোভি
// In the app's build.gradle file. android { defaultConfig{ // Don't configure matchingFallbacks in the defaultConfig block. // Instead, specify fallbacks for a given product flavor in the // productFlavors block, as shown below. } flavorDimensions 'tier' productFlavors { paid { dimension 'tier' // Because the dependency already includes a "paid" flavor in its // "tier" dimension, you don't need to provide a list of fallbacks // for the "paid" flavor. } free { dimension 'tier' // Specifies a sorted list of fallback flavors that the plugin // can try to use when a dependency's matching dimension does // not include a "free" flavor. Specify as many // fallbacks as you like; the plugin selects the first flavor // that's available in the dependency's "tier" dimension. matchingFallbacks = ['demo', 'trial'] } } }
একটি লাইব্রেরি নির্ভরতা একটি স্বাদের মাত্রা অন্তর্ভুক্ত করে যা আপনার অ্যাপে নেই।
উদাহরণস্বরূপ, একটি লাইব্রেরি নির্ভরতা একটি "minApi" মাত্রার জন্য স্বাদ অন্তর্ভুক্ত করে, কিন্তু আপনার অ্যাপে শুধুমাত্র "স্তরের" মাত্রার জন্য স্বাদ অন্তর্ভুক্ত করা হয়। আপনি যখন আপনার অ্যাপের "freeDebug" সংস্করণ তৈরি করতে চান, তখন প্লাগইনটি নির্ভরতার "minApi23Debug" বা "minApi18Debug" সংস্করণ ব্যবহার করবে কিনা তা জানে না।
মনে রাখবেন যে আপনার অ্যাপে যখন লাইব্রেরি নির্ভরতা নয় এমন একটি স্বাদের মাত্রা অন্তর্ভুক্ত করে তখন কোনো সমস্যা নেই। কারণ প্লাগইন নির্ভরশীলতার মধ্যে বিদ্যমান মাত্রার স্বাদের সাথে মেলে। উদাহরণস্বরূপ, যদি একটি নির্ভরতা ABI-এর জন্য একটি মাত্রা অন্তর্ভুক্ত না করে, তাহলে আপনার অ্যাপের "freeX86Debug" সংস্করণটি নির্ভরতার "freeDebug" সংস্করণ ব্যবহার করবে।
প্রতিটি অনুপস্থিত মাত্রা থেকে নির্বাচন করার জন্য প্লাগইনটির ডিফল্ট স্বাদ নির্দিষ্ট করতে
defaultConfig
ব্লকেmissingDimensionStrategy
ব্যবহার করুন, যেমনটি নিম্নলিখিত নমুনায় দেখানো হয়েছে। এছাড়াও আপনিproductFlavors
ব্লকে আপনার নির্বাচনগুলিকে ওভাররাইড করতে পারেন, তাই প্রতিটি স্বাদ একটি অনুপস্থিত মাত্রার জন্য একটি ভিন্ন ম্যাচিং কৌশল নির্দিষ্ট করতে পারে।কোটলিন
// In the app's build.gradle.kts file. android { defaultConfig{ // Specifies a sorted list of flavors that the plugin can try to use from // a given dimension. This tells the plugin to select the "minApi18" flavor // when encountering a dependency that includes a "minApi" dimension. // You can include additional flavor names to provide a // sorted list of fallbacks for the dimension. missingDimensionStrategy("minApi", "minApi18", "minApi23") // Specify a missingDimensionStrategy property for each // dimension that exists in a local dependency but not in your app. missingDimensionStrategy("abi", "x86", "arm64") } flavorDimensions += "tier" productFlavors { create("free") { dimension = "tier" // You can override the default selection at the product flavor // level by configuring another missingDimensionStrategy property // for the "minApi" dimension. missingDimensionStrategy("minApi", "minApi23", "minApi18") } create("paid") {} } }
গ্রোভি
// In the app's build.gradle file. android { defaultConfig{ // Specifies a sorted list of flavors that the plugin can try to use from // a given dimension. This tells the plugin to select the "minApi18" flavor // when encountering a dependency that includes a "minApi" dimension. // You can include additional flavor names to provide a // sorted list of fallbacks for the dimension. missingDimensionStrategy 'minApi', 'minApi18', 'minApi23' // Specify a missingDimensionStrategy property for each // dimension that exists in a local dependency but not in your app. missingDimensionStrategy 'abi', 'x86', 'arm64' } flavorDimensions 'tier' productFlavors { free { dimension 'tier' // You can override the default selection at the product flavor // level by configuring another missingDimensionStrategy property // for the 'minApi' dimension. missingDimensionStrategy 'minApi', 'minApi23', 'minApi18' } paid {} } }
আরও তথ্যের জন্য, অ্যান্ড্রয়েড গ্রেডল প্লাগইন ডিএসএল রেফারেন্সে matchingFallbacks
এবং missingDimensionStrategy
দেখুন।
সাইনিং সেটিংস কনফিগার করুন
Gradle আপনার রিলিজ বিল্ডের APK বা AAB সাইন করে না যদি না আপনি এই বিল্ডের জন্য একটি সাইনিং কনফিগারেশন স্পষ্টভাবে সংজ্ঞায়িত করেন। যদি আপনার কাছে এখনও সাইনিং কী না থাকে, তাহলে অ্যান্ড্রয়েড স্টুডিও ব্যবহার করে একটি আপলোড কী এবং কীস্টোর তৈরি করুন ।
Gradle বিল্ড কনফিগারেশন ব্যবহার করে আপনার রিলিজ বিল্ড টাইপের জন্য সাইনিং কনফিগারেশন ম্যানুয়ালি কনফিগার করতে:
- একটি কীস্টোর তৈরি করুন। একটি কীস্টোর হল একটি বাইনারি ফাইল যাতে ব্যক্তিগত কীগুলির একটি সেট থাকে। আপনাকে অবশ্যই আপনার কীস্টোর একটি নিরাপদ এবং নিরাপদ জায়গায় রাখতে হবে।
- একটি ব্যক্তিগত কী তৈরি করুন। বিতরণের জন্য আপনার অ্যাপে স্বাক্ষর করতে একটি ব্যক্তিগত কী ব্যবহার করা হয় এবং অ্যাপের সাথে কখনই অন্তর্ভুক্ত করা হয় না বা অননুমোদিত তৃতীয় পক্ষের কাছে প্রকাশ করা হয় না।
মডিউল-স্তরের
build.gradle.kts
ফাইলে সাইনিং কনফিগারেশন যোগ করুন:কোটলিন
... android { ... defaultConfig {...} signingConfigs { create("release") { storeFile = file("myreleasekey.keystore") storePassword = "password" keyAlias = "MyReleaseKey" keyPassword = "password" } } buildTypes { getByName("release") { ... signingConfig = signingConfigs.getByName("release") } } }
গ্রোভি
... android { ... defaultConfig {...} signingConfigs { release { storeFile file("myreleasekey.keystore") storePassword "password" keyAlias "MyReleaseKey" keyPassword "password" } } buildTypes { release { ... signingConfig signingConfigs.release } } }
দ্রষ্টব্য: বিল্ড ফাইলের ভিতরে আপনার রিলিজ কী এবং কীস্টোরের পাসওয়ার্ডগুলি অন্তর্ভুক্ত করা একটি ভাল সুরক্ষা অনুশীলন নয়। পরিবর্তে, এনভায়রনমেন্ট ভেরিয়েবল থেকে এই পাসওয়ার্ডগুলি পেতে বিল্ড ফাইলটি কনফিগার করুন বা বিল্ড প্রক্রিয়া আপনাকে এই পাসওয়ার্ডগুলির জন্য অনুরোধ করবে।
পরিবেশ ভেরিয়েবল থেকে এই পাসওয়ার্ডগুলি পেতে:
কোটলিন
storePassword = System.getenv("KSTOREPWD") keyPassword = System.getenv("KEYPWD")
গ্রোভি
storePassword System.getenv("KSTOREPWD") keyPassword System.getenv("KEYPWD")
বিকল্পভাবে, আপনি একটি স্থানীয় বৈশিষ্ট্য ফাইল থেকে কীস্টোর লোড করতে পারেন। নিরাপত্তার কারণে, উৎস নিয়ন্ত্রণে এই ফাইলটি যোগ করবেন না। পরিবর্তে, প্রতিটি বিকাশকারীর জন্য এটি স্থানীয়ভাবে সেট আপ করুন। আরও জানতে, আপনার বিল্ড ফাইল থেকে স্বাক্ষর তথ্য সরান পড়ুন।
আপনি এই প্রক্রিয়াটি সম্পূর্ণ করার পরে, আপনি আপনার অ্যাপটি বিতরণ করতে এবং Google Play-এ প্রকাশ করতে পারেন৷
সতর্কতা: আপনার কীস্টোর এবং প্রাইভেট কী একটি নিরাপদ এবং সুরক্ষিত জায়গায় রাখুন এবং নিশ্চিত করুন যে আপনার কাছে সেগুলির নিরাপদ ব্যাকআপ আছে। আপনি যদি প্লে অ্যাপ সাইনিং ব্যবহার করেন এবং আপনি আপনার আপলোড কী হারিয়ে ফেলেন, আপনি প্লে কনসোল ব্যবহার করে রিসেটের অনুরোধ করতে পারেন। আপনি যদি প্লে অ্যাপ সাইনিং ছাড়াই কোনো অ্যাপ প্রকাশ করেন (আগস্ট 2021 সালের আগে তৈরি অ্যাপের জন্য) এবং আপনি আপনার অ্যাপ সাইনিং কী হারিয়ে ফেলেন, তাহলে আপনি আপনার অ্যাপে কোনো আপডেট প্রকাশ করতে পারবেন না, কারণ আপনাকে অবশ্যই একই কী দিয়ে আপনার অ্যাপের সব সংস্করণে সাইন ইন করতে হবে।
Wear OS অ্যাপে সাইন ইন করা হচ্ছে
Wear OS অ্যাপ প্রকাশ করার সময়, ঘড়ির APK এবং ঐচ্ছিক ফোন APK উভয়কেই একই কী দিয়ে স্বাক্ষর করতে হবে। Wear OS অ্যাপের প্যাকেজিং এবং সাইনিং সম্পর্কে আরও তথ্যের জন্য, Wear অ্যাপের প্যাকেজ এবং বিতরণ দেখুন।
,এই পৃষ্ঠাটি আপনাকে দেখায় কিভাবে আপনি একটি একক প্রকল্প থেকে আপনার অ্যাপের বিভিন্ন সংস্করণ তৈরি করতে বিল্ড ভেরিয়েন্ট কনফিগার করতে পারেন এবং কীভাবে আপনার নির্ভরতা এবং সাইনিং কনফিগারেশনগুলি সঠিকভাবে পরিচালনা করবেন।
প্রতিটি বিল্ড ভেরিয়েন্ট আপনার অ্যাপের একটি ভিন্ন সংস্করণ উপস্থাপন করে যা আপনি তৈরি করতে পারেন। উদাহরণস্বরূপ, আপনি আপনার অ্যাপের একটি সংস্করণ তৈরি করতে চাইতে পারেন যা সীমিত সামগ্রীর সাথে বিনামূল্যে, এবং অন্য একটি অর্থপ্রদানের সংস্করণ যাতে আরও অন্তর্ভুক্ত থাকে। আপনি আপনার অ্যাপের বিভিন্ন সংস্করণও তৈরি করতে পারেন যা API স্তর বা অন্যান্য ডিভাইসের বৈচিত্রের উপর ভিত্তি করে বিভিন্ন ডিভাইসকে লক্ষ্য করে।
বিল্ড ভেরিয়েন্টগুলি আপনার বিল্ডের ধরন এবং পণ্যের স্বাদে কনফিগার করা সেটিংস, কোড এবং সংস্থানগুলিকে একত্রিত করতে নিয়মের একটি নির্দিষ্ট সেট ব্যবহার করে গ্রেডলের ফলাফল। যদিও আপনি বিল্ড ভেরিয়েন্টগুলি সরাসরি কনফিগার করেন না, আপনি বিল্ডের ধরন এবং পণ্যের স্বাদগুলি কনফিগার করেন যা তাদের গঠন করে।
উদাহরণস্বরূপ, একটি "ডেমো" পণ্যের স্বাদ নির্দিষ্ট বৈশিষ্ট্য এবং ডিভাইসের প্রয়োজনীয়তাগুলি নির্দিষ্ট করতে পারে, যেমন কাস্টম সোর্স কোড, সংস্থান এবং ন্যূনতম API স্তর, যখন "ডিবাগ" বিল্ড টাইপ বিভিন্ন বিল্ড এবং প্যাকেজিং সেটিংস প্রয়োগ করে, যেমন ডিবাগ বিকল্প এবং সাইনিং কী। বিল্ড ভেরিয়েন্ট যা এই দুটিকে একত্রিত করে তা হল আপনার অ্যাপের "ডেমোডিবাগ" সংস্করণ, এবং এতে "ডেমো" পণ্যের স্বাদ, "ডিবাগ" বিল্ড টাইপ এবং main/
উৎস সেটের অন্তর্ভুক্ত কনফিগারেশন এবং সংস্থানগুলির সংমিশ্রণ অন্তর্ভুক্ত রয়েছে।
বিল্ড প্রকারগুলি কনফিগার করুন
আপনি মডিউল-স্তরের build.gradle.kts
ফাইলের android
ব্লকের ভিতরে বিল্ড প্রকারগুলি তৈরি এবং কনফিগার করতে পারেন। আপনি যখন একটি নতুন মডিউল তৈরি করেন, তখন Android স্টুডিও স্বয়ংক্রিয়ভাবে ডিবাগ এবং রিলিজ বিল্ডের ধরন তৈরি করে। যদিও বিল্ড কনফিগারেশন ফাইলে ডিবাগ বিল্ড টাইপ প্রদর্শিত হয় না, তবে অ্যান্ড্রয়েড স্টুডিও এটিকে debuggable true
দিয়ে কনফিগার করে। এটি আপনাকে নিরাপদ অ্যান্ড্রয়েড ডিভাইসে অ্যাপটিকে ডিবাগ করতে দেয় এবং জেনেরিক ডিবাগ কীস্টোর দিয়ে অ্যাপ সাইনিং কনফিগার করতে দেয়।
আপনি যদি নির্দিষ্ট সেটিংস যোগ করতে বা পরিবর্তন করতে চান তবে আপনি আপনার কনফিগারেশনে ডিবাগ বিল্ড টাইপ যোগ করতে পারেন। নিচের নমুনাটি ডিবাগ বিল্ড টাইপের জন্য একটি applicationIdSuffix
নির্দিষ্ট করে এবং একটি "স্টেজিং" বিল্ড টাইপ কনফিগার করে যা ডিবাগ বিল্ড টাইপ থেকে সেটিংস ব্যবহার করে আরম্ভ করা হয়:
কোটলিন
android { defaultConfig { manifestPlaceholders["hostName"] = "www.example.com" ... } buildTypes { getByName("release") { isMinifyEnabled = true proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro") } getByName("debug") { applicationIdSuffix = ".debug" isDebuggable = true } /** * The `initWith` property lets you copy configurations from other build types, * then configure only the settings you want to change. This one copies the debug build * type, and then changes the manifest placeholder and application ID. */ create("staging") { initWith(getByName("debug")) manifestPlaceholders["hostName"] = "internal.example.com" applicationIdSuffix = ".debugStaging" } } }
গ্রোভি
android { defaultConfig { manifestPlaceholders = [hostName:"www.example.com"] ... } buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } debug { applicationIdSuffix ".debug" debuggable true } /** * The `initWith` property lets you copy configurations from other build types, * then configure only the settings you want to change. This one copies the debug build * type, and then changes the manifest placeholder and application ID. */ staging { initWith debug manifestPlaceholders = [hostName:"internal.example.com"] applicationIdSuffix ".debugStaging" } } }
দ্রষ্টব্য: আপনি যখন একটি বিল্ড কনফিগারেশন ফাইলে পরিবর্তন করেন, তখন Android স্টুডিওর প্রয়োজন হয় যে আপনি নতুন কনফিগারেশনের সাথে আপনার প্রকল্পটি সিঙ্ক করুন৷ আপনার প্রজেক্ট সিঙ্ক করতে, নোটিফিকেশন বারে Sync Now- এ ক্লিক করুন যা আপনি যখন কোনও পরিবর্তন করেন বা সিঙ্ক প্রজেক্টে ক্লিক করেন টুলবার থেকে। যদি অ্যান্ড্রয়েড স্টুডিও আপনার কনফিগারেশনে কোনো ত্রুটি লক্ষ্য করে, তাহলে বার্তা উইন্ডোটি সমস্যাটি বর্ণনা করতে দেখায়।
আপনি বিল্ড প্রকারের সাথে কনফিগার করতে পারেন এমন সমস্ত বৈশিষ্ট্য সম্পর্কে আরও জানতে, BuildType
রেফারেন্স পড়ুন।
পণ্যের স্বাদ কনফিগার করুন
পণ্যের স্বাদ তৈরি করা বিল্ড প্রকার তৈরির অনুরূপ। আপনার বিল্ড কনফিগারেশনে প্রোডাক্ট productFlavors
ব্লকে পণ্যের স্বাদ যোগ করুন এবং আপনি যে সেটিংস চান তা অন্তর্ভুক্ত করুন। পণ্যের স্বাদগুলি defaultConfig
মতো একই বৈশিষ্ট্যগুলিকে সমর্থন করে, কারণ defaultConfig
আসলে ProductFlavor
শ্রেণীর অন্তর্গত। এর মানে হল আপনি defaultConfig
ব্লকে সমস্ত স্বাদের জন্য বেস কনফিগারেশন প্রদান করতে পারেন, এবং প্রতিটি স্বাদ এই ডিফল্ট মানগুলির যেকোনো পরিবর্তন করতে পারে, যেমন applicationId
। অ্যাপ্লিকেশন আইডি সম্পর্কে আরও জানতে, অ্যাপ্লিকেশন আইডি সেট করুন পড়ুন।
দ্রষ্টব্য: আপনাকে এখনও main/
ম্যানিফেস্ট ফাইলে package
বৈশিষ্ট্য ব্যবহার করে একটি প্যাকেজের নাম উল্লেখ করতে হবে। R
শ্রেণীতে উল্লেখ করতে বা কোনো আপেক্ষিক কার্যকলাপ বা পরিষেবা নিবন্ধন সমাধানের জন্য আপনাকে অবশ্যই আপনার উত্স কোডে সেই প্যাকেজের নামটি ব্যবহার করতে হবে। এটি আপনাকে আপনার সোর্স কোড পরিবর্তন না করেই প্রতিটি পণ্যের স্বাদকে প্যাকেজিং এবং বিতরণের জন্য একটি অনন্য আইডি দিতে applicationId
ব্যবহার করতে দেয়।
সমস্ত স্বাদ অবশ্যই একটি নামযুক্ত স্বাদের মাত্রার অন্তর্গত হতে হবে, যা পণ্যের স্বাদের একটি গ্রুপ। আপনি একটি স্বাদ মাত্রা সব স্বাদ বরাদ্দ করা আবশ্যক; অন্যথায়, আপনি নিম্নলিখিত বিল্ড ত্রুটি পাবেন।
Error: All flavors must now belong to a named flavor dimension. The flavor 'flavor_name' is not assigned to a flavor dimension.
যদি একটি প্রদত্ত মডিউল শুধুমাত্র একটি স্বাদের মাত্রা নির্দিষ্ট করে, তাহলে Android Gradle প্লাগইন স্বয়ংক্রিয়ভাবে মডিউলের সমস্ত স্বাদকে সেই মাত্রায় বরাদ্দ করে।
নিম্নলিখিত কোড নমুনা "সংস্করণ" নামে একটি স্বাদের মাত্রা তৈরি করে এবং "ডেমো" এবং "সম্পূর্ণ" পণ্যের স্বাদ যোগ করে। এই স্বাদগুলি তাদের নিজস্ব applicationIdSuffix
এবং versionNameSuffix
প্রদান করে:
কোটলিন
android { ... defaultConfig {...} buildTypes { getByName("debug"){...} getByName("release"){...} } // Specifies one flavor dimension. flavorDimensions += "version" productFlavors { create("demo") { // Assigns this product flavor to the "version" flavor dimension. // If you are using only one dimension, this property is optional, // and the plugin automatically assigns all the module's flavors to // that dimension. dimension = "version" applicationIdSuffix = ".demo" versionNameSuffix = "-demo" } create("full") { dimension = "version" applicationIdSuffix = ".full" versionNameSuffix = "-full" } } }
গ্রোভি
android { ... defaultConfig {...} buildTypes { debug{...} release{...} } // Specifies one flavor dimension. flavorDimensions "version" productFlavors { demo { // Assigns this product flavor to the "version" flavor dimension. // If you are using only one dimension, this property is optional, // and the plugin automatically assigns all the module's flavors to // that dimension. dimension "version" applicationIdSuffix ".demo" versionNameSuffix "-demo" } full { dimension "version" applicationIdSuffix ".full" versionNameSuffix "-full" } } }
দ্রষ্টব্য: আপনার যদি একটি লিগ্যাসি অ্যাপ (আগস্ট 2021 সালের আগে তৈরি) থাকে যা আপনি Google Play-তে APK ব্যবহার করে বিতরণ করেন, Google Play-তে একাধিক APK সমর্থন ব্যবহার করে আপনার অ্যাপ বিতরণ করতে, সমস্ত ভেরিয়েন্টে একই applicationId
মান বরাদ্দ করুন এবং প্রতিটি ভেরিয়েন্টকে একটি ভিন্ন versionCode
দিন। আপনার অ্যাপের বিভিন্ন রূপকে Google Play-তে আলাদা অ্যাপ হিসেবে বিতরণ করতে, আপনাকে প্রতিটি ভেরিয়েন্টে একটি আলাদা applicationId
বরাদ্দ করতে হবে।
আপনি আপনার পণ্যের স্বাদগুলি তৈরি এবং কনফিগার করার পরে, বিজ্ঞপ্তি বারে এখন সিঙ্ক করুন ক্লিক করুন৷ একবার সিঙ্ক সম্পূর্ণ হলে, গ্রেডল স্বয়ংক্রিয়ভাবে আপনার বিল্ডের ধরন এবং পণ্যের স্বাদের উপর ভিত্তি করে বিল্ড ভেরিয়েন্ট তৈরি করে এবং <product-flavor><Build-Type>
অনুসারে তাদের নাম দেয়। উদাহরণস্বরূপ, আপনি যদি "ডেমো" এবং "সম্পূর্ণ" পণ্যের স্বাদ তৈরি করেন এবং ডিফল্ট "ডিবাগ" এবং "রিলিজ" বিল্ডের ধরন রাখেন, তাহলে Gradle নিম্নলিখিত বিল্ড ভেরিয়েন্টগুলি তৈরি করে:
-
demoDebug
-
demoRelease
-
fullDebug
-
fullRelease
কোন বিল্ড ভেরিয়েন্টটি তৈরি এবং চালানো হবে তা নির্বাচন করতে, বিল্ড > বিল্ড ভেরিয়েন্ট নির্বাচন করুন এবং মেনু থেকে একটি বিল্ড ভেরিয়েন্ট নির্বাচন করুন। প্রতিটি বিল্ড বৈকল্পিককে নিজস্ব বৈশিষ্ট্য এবং সংস্থানগুলির সাথে কাস্টমাইজ করা শুরু করতে, আপনাকে এই পৃষ্ঠায় বর্ণিত উত্স সেটগুলি তৈরি এবং পরিচালনা করতে হবে৷
বিল্ড ভেরিয়েন্টের জন্য অ্যাপ্লিকেশন আইডি পরিবর্তন করুন
আপনি যখন আপনার অ্যাপের জন্য একটি APK বা AAB তৈরি করেন, তখন বিল্ড টুলগুলি নিম্নলিখিত উদাহরণে দেখানো হয়েছে, build.gradle.kts
ফাইল থেকে defaultConfig
ব্লকে সংজ্ঞায়িত অ্যাপ্লিকেশন আইডি দিয়ে অ্যাপটিকে ট্যাগ করে। যাইহোক, যদি আপনি Google Play Store-এ "ফ্রি" এবং "প্রো" সংস্করণের মতো আলাদা তালিকা হিসাবে প্রদর্শিত হওয়ার জন্য আপনার অ্যাপের বিভিন্ন সংস্করণ তৈরি করতে চান, তাহলে আপনাকে আলাদা আলাদা বিল্ড ভেরিয়েন্ট তৈরি করতে হবে যার প্রত্যেকটির আলাদা অ্যাপ্লিকেশন আইডি আছে।
এই ক্ষেত্রে, প্রতিটি বিল্ড বৈকল্পিককে একটি পৃথক পণ্যের স্বাদ হিসাবে সংজ্ঞায়িত করুন। productFlavors
ব্লকের প্রতিটি স্বাদের জন্য, আপনি applicationId
বৈশিষ্ট্যটি পুনরায় সংজ্ঞায়িত করতে পারেন, অথবা আপনি applicationIdSuffix
ব্যবহার করে ডিফল্ট অ্যাপ্লিকেশন আইডিতে একটি সেগমেন্ট যুক্ত করতে পারেন, যেমনটি এখানে দেখানো হয়েছে:
কোটলিন
android { defaultConfig { applicationId = "com.example.myapp" } productFlavors { create("free") { applicationIdSuffix = ".free" } create("pro") { applicationIdSuffix = ".pro" } } }
গ্রোভি
android { defaultConfig { applicationId "com.example.myapp" } productFlavors { free { applicationIdSuffix ".free" } pro { applicationIdSuffix ".pro" } } }
এইভাবে, "ফ্রি" পণ্যের স্বাদের জন্য অ্যাপ্লিকেশন আইডি হল "com.example.myapp.free"৷
আপনি আপনার বিল্ড টাইপের উপর ভিত্তি করে একটি সেগমেন্ট যুক্ত করতে applicationIdSuffix
ব্যবহার করতে পারেন, যেমনটি এখানে দেখানো হয়েছে:
কোটলিন
android { ... buildTypes { getByName("debug") { applicationIdSuffix = ".debug" } } }
গ্রোভি
android { ... buildTypes { debug { applicationIdSuffix ".debug" } } }
যেহেতু Gradle প্রোডাক্ট ফ্লেভারের পরে বিল্ড টাইপ কনফিগারেশন প্রয়োগ করে, তাই "ফ্রি ডিবাগ" বিল্ড ভেরিয়েন্টের অ্যাপ্লিকেশন আইডি হল "com.example.myapp.free.debug"। আপনি যখন একই ডিভাইসে ডিবাগ এবং রিলিজ বিল্ড করতে চান তখন এটি কার্যকর, কারণ দুটি অ্যাপের একই অ্যাপ্লিকেশন আইডি থাকতে পারে না।
আপনার যদি একটি লিগ্যাসি অ্যাপ (আগস্ট 2021 সালের আগে তৈরি) থাকে যেটি আপনি Google Play-তে APK ব্যবহার করে বিতরণ করেন এবং আপনি একই অ্যাপ তালিকা ব্যবহার করে একাধিক APK বিতরণ করতে চান যেগুলি প্রতিটি আলাদা ডিভাইস কনফিগারেশনকে লক্ষ্য করে, যেমন API স্তর, তাহলে আপনাকে অবশ্যই প্রতিটি বিল্ড ভেরিয়েন্টের জন্য একই অ্যাপ্লিকেশন আইডি ব্যবহার করতে হবে তবে প্রতিটি APKকে একটি ভিন্নversionCode
দিতে হবে। আরও তথ্যের জন্য, একাধিক APK সমর্থন সম্পর্কে পড়ুন। এএবিএস ব্যবহার করে প্রকাশনা প্রভাবিত হয় না, কারণ এটি একটি একক নিদর্শন ব্যবহার করে যা ডিফল্টরূপে একক সংস্করণ কোড এবং অ্যাপ্লিকেশন আইডি ব্যবহার করে। টিপ: আপনার যদি আপনার ম্যানিফেস্ট ফাইলে অ্যাপ্লিকেশন আইডিটি উল্লেখ করতে হয় তবে আপনি কোনও ম্যানিফেস্ট অ্যাট্রিবিউটে ${applicationId}
স্থানধারক ব্যবহার করতে পারেন। একটি বিল্ড চলাকালীন, গ্রেড এই ট্যাগটি প্রকৃত অ্যাপ্লিকেশন আইডি দিয়ে প্রতিস্থাপন করে। আরও তথ্যের জন্য, ম্যানিফেস্টে ইনজেক্ট বিল্ড ভেরিয়েবলগুলি দেখুন।
গন্ধ মাত্রা সঙ্গে একাধিক পণ্য স্বাদ একত্রিত
কিছু ক্ষেত্রে, আপনি একাধিক পণ্য স্বাদ থেকে কনফিগারেশনগুলি একত্রিত করতে চাইতে পারেন। উদাহরণস্বরূপ, আপনি এপিআই স্তরের উপর ভিত্তি করে "পূর্ণ" এবং "ডেমো" পণ্য স্বাদের জন্য বিভিন্ন কনফিগারেশন তৈরি করতে চাইতে পারেন। এটি করার জন্য, অ্যান্ড্রয়েড গ্রেডল প্লাগইন আপনাকে স্বাদের মাত্রা হিসাবে পণ্য স্বাদের একাধিক গ্রুপ তৈরি করতে দেয়।
আপনার অ্যাপ তৈরি করার সময়, গ্রেডল চূড়ান্ত বিল্ড বৈকল্পিক তৈরি করতে বিল্ড টাইপ কনফিগারেশনের সাথে আপনার সংজ্ঞায়িত প্রতিটি ফ্লেভার ডাইমেনশন থেকে একটি প্রোডাক্ট ফ্লেভার কনফিগারেশন একত্রিত করে। গ্রেডল একই স্বাদ মাত্রার সাথে সম্পর্কিত পণ্যের স্বাদগুলিকে একত্রিত করে না।
নিম্নলিখিত কোড নমুনাটি "সম্পূর্ণ" এবং "ডেমো" পণ্যের স্বাদ এবং এপিআই স্তরের উপর ভিত্তি করে গ্রুপ পণ্য স্বাদ কনফিগারেশনের একটি "এপিআই" গন্ধের মাত্রা গ্রুপ করতে একটি "মোড" গন্ধের মাত্রা তৈরি করতে flavorDimensions
সম্পত্তি ব্যবহার করে:
কোটলিন
android { ... buildTypes { getByName("debug") {...} getByName("release") {...} } // Specifies the flavor dimensions you want to use. The order in which you // list the dimensions determines their priority, from highest to lowest, // when Gradle merges variant sources and configurations. You must assign // each product flavor you configure to one of the flavor dimensions. flavorDimensions += listOf("api", "mode") productFlavors { create("demo") { // Assigns this product flavor to the "mode" flavor dimension. dimension = "mode" ... } create("full") { dimension = "mode" ... } // Configurations in the "api" product flavors override those in "mode" // flavors and the defaultConfig block. Gradle determines the priority // between flavor dimensions based on the order in which they appear next // to the flavorDimensions property, with the first dimension having a higher // priority than the second, and so on. create("minApi24") { dimension = "api" minSdk = 24 // To ensure the target device receives the version of the app with // the highest compatible API level, assign version codes in increasing // value with API level. versionCode = 30000 + (android.defaultConfig.versionCode ?: 0) versionNameSuffix = "-minApi24" ... } create("minApi23") { dimension = "api" minSdk = 23 versionCode = 20000 + (android.defaultConfig.versionCode ?: 0) versionNameSuffix = "-minApi23" ... } create("minApi21") { dimension = "api" minSdk = 21 versionCode = 10000 + (android.defaultConfig.versionCode ?: 0) versionNameSuffix = "-minApi21" ... } } } ...
গ্রোভি
android { ... buildTypes { debug {...} release {...} } // Specifies the flavor dimensions you want to use. The order in which you // list the dimensions determines their priority, from highest to lowest, // when Gradle merges variant sources and configurations. You must assign // each product flavor you configure to one of the flavor dimensions. flavorDimensions "api", "mode" productFlavors { demo { // Assigns this product flavor to the "mode" flavor dimension. dimension "mode" ... } full { dimension "mode" ... } // Configurations in the "api" product flavors override those in "mode" // flavors and the defaultConfig block. Gradle determines the priority // between flavor dimensions based on the order in which they appear next // to the flavorDimensions property, with the first dimension having a higher // priority than the second, and so on. minApi24 { dimension "api" minSdkVersion 24 // To ensure the target device receives the version of the app with // the highest compatible API level, assign version codes in increasing // value with API level. versionCode 30000 + android.defaultConfig.versionCode versionNameSuffix "-minApi24" ... } minApi23 { dimension "api" minSdkVersion 23 versionCode 20000 + android.defaultConfig.versionCode versionNameSuffix "-minApi23" ... } minApi21 { dimension "api" minSdkVersion 21 versionCode 10000 + android.defaultConfig.versionCode versionNameSuffix "-minApi21" ... } } } ...
গ্রেডল তৈরি করে বিল্ড ভেরিয়েন্টগুলির সংখ্যা প্রতিটি গন্ধের মাত্রায় স্বাদের সংখ্যার পণ্য এবং আপনার কনফিগার করা বিল্ড ধরণের সংখ্যার সমান। যখন গ্রেডের নাম প্রতিটি বিল্ড বৈকল্পিক বা সংশ্লিষ্ট শিল্পকর্মগুলি তৈরি করে, উচ্চ-অগ্রাধিকারের স্বাদ মাত্রার সাথে সম্পর্কিত পণ্যের স্বাদগুলি প্রথমে উপস্থিত হয়, তারপরে নিম্ন-অগ্রাধিকারের মাত্রাগুলি থেকে শুরু করে, তারপরে বিল্ড টাইপ হয়।
উদাহরণ হিসাবে পূর্ববর্তী বিল্ড কনফিগারেশনটি ব্যবহার করে, গ্রেডল নিম্নলিখিত নামকরণ স্কিম সহ মোট 12 টি বিল্ড ভেরিয়েন্ট তৈরি করে:
- বিল্ড ভেরিয়েন্ট:
[minApi24, minApi23, minApi21][Demo, Full][Debug, Release]
- সংশ্লিষ্ট এপিকে:
app-[minApi24, minApi23, minApi21]-[demo, full]-[debug, release].apk
- যেমন,
- বিল্ড ভেরিয়েন্ট:
minApi24DemoDebug
- সংশ্লিষ্ট এপিকে:
app-minApi24-demo-debug.apk
উত্স সেট ডিরেক্টরিগুলি ছাড়াও আপনি প্রতিটি পৃথক পণ্য গন্ধের জন্য তৈরি করতে পারেন এবং বৈকল্পিক তৈরি করতে পারেন, আপনি পণ্যের স্বাদের প্রতিটি সংমিশ্রণের জন্য উত্স সেট ডিরেক্টরিও তৈরি করতে পারেন। উদাহরণস্বরূপ, আপনি src/demoMinApi24/java/
ডিরেক্টরিতে জাভা উত্সগুলি তৈরি এবং যুক্ত করতে পারেন এবং গ্রেডল কেবল তখনই সেই উত্সগুলি ব্যবহার করে যখন এই দুটি পণ্য স্বাদকে একত্রিত করে এমন একটি বৈকল্পিক তৈরি করে।
পণ্য স্বাদ সংমিশ্রণের জন্য আপনার তৈরি উত্স সেটগুলি প্রতিটি পৃথক পণ্যের স্বাদের অন্তর্ভুক্ত উত্স সেটগুলির চেয়ে বেশি অগ্রাধিকার রয়েছে। উত্স সেটগুলি এবং কীভাবে গ্রেডল সংস্থানগুলি একীভূত করে সে সম্পর্কে আরও জানতে, উত্স সেটগুলি কীভাবে তৈরি করবেন সে সম্পর্কে বিভাগটি পড়ুন।
ফিল্টার বৈকল্পিক
Gradle আপনার কনফিগার করা পণ্যের স্বাদ এবং বিল্ড প্রকারের প্রতিটি সম্ভাব্য সমন্বয়ের জন্য একটি বিল্ড বৈকল্পিক তৈরি করে। তবে, এমন কিছু বিল্ড ভেরিয়েন্ট থাকতে পারে যা আপনার প্রয়োজন নেই বা আপনার প্রকল্পের প্রসঙ্গে এটি বোঝায় না। নির্দিষ্ট বিল্ড ভেরিয়েন্ট কনফিগারেশনগুলি অপসারণ করতে, আপনার মডিউল-স্তর build.gradle.kts
ফাইলটিতে একটি বৈকল্পিক ফিল্টার তৈরি করুন।
উদাহরণ হিসাবে পূর্ববর্তী বিভাগ থেকে বিল্ড কনফিগারেশনটি ব্যবহার করে, ধরুন আপনি অ্যাপ্লিকেশনটির ডেমো সংস্করণের জন্য কেবল এপিআই স্তর 23 এবং উচ্চতর সমর্থন করার পরিকল্পনা করছেন। "মিনাপি 21" এবং "ডেমো" পণ্য স্বাদগুলি একত্রিত করে এমন সমস্ত বিল্ড ভেরিয়েন্ট কনফিগারেশনগুলি ফিল্টার করতে আপনি variantFilter
ব্লকটি ব্যবহার করতে পারেন:
কোটলিন
android { ... buildTypes {...} flavorDimensions += listOf("api", "mode") productFlavors { create("demo") {...} create("full") {...} create("minApi24") {...} create("minApi23") {...} create("minApi21") {...} } } androidComponents { beforeVariants { variantBuilder -> // To check for a certain build type, use variantBuilder.buildType == "<buildType>" if (variantBuilder.productFlavors.containsAll(listOf("api" to "minApi21", "mode" to "demo"))) { // Gradle ignores any variants that satisfy the conditions above. variantBuilder.enable = false } } } ...
গ্রোভি
android { ... buildTypes {...} flavorDimensions "api", "mode" productFlavors { demo {...} full {...} minApi24 {...} minApi23 {...} minApi21 {...} } variantFilter { variant -> def names = variant.flavors*.name // To check for a certain build type, use variant.buildType.name == "<buildType>" if (names.contains("minApi21") && names.contains("demo")) { // Gradle ignores any variants that satisfy the conditions above. setIgnore(true) } } } ...
একবার আপনি আপনার বিল্ড কনফিগারেশনে একটি বৈকল্পিক ফিল্টার যুক্ত করার পরে এবং বিজ্ঞপ্তি বারে এখনই সিঙ্ক ক্লিক করুন, গ্রেডল আপনার নির্দিষ্ট শর্তগুলি পূরণ করে এমন কোনও বিল্ড বৈকল্পগুলি উপেক্ষা করে। আপনি যখন বিল্ড> মেনু বার থেকে বিল্ড ভেরিয়েন্ট নির্বাচন করুন বা ভেরিয়েন্টগুলি তৈরি করবেন তখন বিল্ড ভেরিয়েন্টগুলি মেনুতে আর উপস্থিত হয় না সরঞ্জাম উইন্ডো বারে।
সোর্স সেট তৈরি করুন
ডিফল্টরূপে, অ্যান্ড্রয়েড স্টুডিও আপনার সমস্ত বিল্ড ভেরিয়েন্টের মধ্যে শেয়ার করতে চান এমন সবকিছুর জন্য main/
উৎস সেট এবং ডিরেক্টরি তৈরি করে। তবে, নির্দিষ্ট বিল্ড প্রকার, পণ্যের স্বাদ, পণ্যের স্বাদের সংমিশ্রণগুলি ( স্বাদের মাত্রা ব্যবহার করার সময়) এবং রূপগুলি তৈরি করার জন্য কোন ফাইলগুলি গ্রেডল সংকলন এবং প্যাকেজগুলি ঠিক তা নিয়ন্ত্রণ করতে আপনি নতুন উত্স সেট তৈরি করতে পারেন।
উদাহরণস্বরূপ, আপনি main/
উৎস সেটে মৌলিক কার্যকারিতা নির্ধারণ করতে পারেন এবং বিভিন্ন ক্লায়েন্টের জন্য আপনার অ্যাপের ব্র্যান্ডিং পরিবর্তন করতে পণ্যের স্বাদের উৎস সেট ব্যবহার করতে পারেন, অথবা শুধুমাত্র ডিবাগ বিল্ড টাইপ ব্যবহার করে এমন বিল্ড ভেরিয়েন্টের জন্য বিশেষ অনুমতি এবং লগিং কার্যকারিতা অন্তর্ভুক্ত করতে পারেন।
গ্রেডল আশা করে যে উত্স সেট ফাইল এবং ডিরেক্টরিগুলি একটি নির্দিষ্ট উপায়ে সংগঠিত হবে, main/
উত্স সেটের মতো। উদাহরণস্বরূপ, গ্রেডল আপনার "ডিবাগ" বিল্ড টাইপের সাথে সুনির্দিষ্ট যেগুলি src/debug/kotlin/
বা src/debug/java/
ডিরেক্টরিতে অবস্থিত তা নির্দিষ্ট কোটলিন বা জাভা ক্লাস ফাইলগুলি প্রত্যাশা করে।
অ্যান্ড্রয়েড গ্রেডল প্লাগইন একটি দরকারী গ্রেডল টাস্ক সরবরাহ করে যা আপনাকে দেখায় যে কীভাবে আপনার প্রতিটি বিল্ড প্রকার, পণ্যের স্বাদ এবং রূপগুলি তৈরি করার জন্য আপনার ফাইলগুলি কীভাবে সংগঠিত করতে হয়। উদাহরণস্বরূপ, টাস্ক আউটপুট থেকে নিম্নলিখিত নমুনাটি বর্ণনা করে যেখানে গ্রেডল "ডিবাগ" বিল্ড টাইপের জন্য নির্দিষ্ট ফাইলগুলি খুঁজে পাওয়ার প্রত্যাশা করে:
------------------------------------------------------------ Project :app ------------------------------------------------------------ ... debug ---- Compile configuration: debugCompile build.gradle name: android.sourceSets.debug Java sources: [app/src/debug/java] Kotlin sources: [app/src/debug/kotlin, app/src/debug/java] Manifest file: app/src/debug/AndroidManifest.xml Android resources: [app/src/debug/res] Assets: [app/src/debug/assets] AIDL sources: [app/src/debug/aidl] RenderScript sources: [app/src/debug/rs] JNI sources: [app/src/debug/jni] JNI libraries: [app/src/debug/jniLibs] Java-style resources: [app/src/debug/resources]
এই আউটপুটটি দেখতে, নিম্নলিখিত হিসাবে এগিয়ে যান:
- সরঞ্জাম উইন্ডো বারে গ্রেড ক্লিক করুন।
মাই অ্যাপ্লিকেশন> টাস্কস> অ্যান্ড্রয়েড এবং ডাবল-ক্লিক উত্সগুলিতে নেভিগেট করুন।
টাস্ক ফোল্ডারটি দেখতে, আপনাকে অবশ্যই সিঙ্কের সময় গ্রেডলকে টাস্ক তালিকাটি তৈরি করতে হবে। এটি করতে, এই পদক্ষেপগুলি অনুসরণ করুন:
- ফাইল> সেটিংস> পরীক্ষামূলক ( অ্যান্ড্রয়েড স্টুডিও> সেটিংস> ম্যাকোসে পরীক্ষামূলক ) ক্লিক করুন।
- নির্বাসন গ্রেড সিঙ্কের সময় গ্রেডল টাস্ক তালিকা তৈরি করবেন না ।
- গ্রেডল টাস্কটি কার্যকর করার পরে, রান উইন্ডোটি আউটপুটটি প্রদর্শন করতে খোলে।
দ্রষ্টব্য: টাস্ক আউটপুটটি আপনাকে দেখায় যে কীভাবে আপনার অ্যাপ্লিকেশনটির জন্য পরীক্ষা চালানোর জন্য আপনি যে ফাইলগুলি ব্যবহার করতে চান তার জন্য উত্স সেটগুলি কীভাবে সংগঠিত করবেন, যেমন test/
এবং androidTest/
পরীক্ষার উত্স সেটগুলি ।
আপনি যখন একটি নতুন বিল্ড ভেরিয়েন্ট তৈরি করেন, তখন অ্যান্ড্রয়েড স্টুডিও আপনার জন্য সোর্স সেট ডিরেক্টরি তৈরি করে না, তবে এটি আপনাকে সাহায্য করার জন্য কয়েকটি বিকল্প দেয়। উদাহরণস্বরূপ, আপনার "ডিবাগ" বিল্ড টাইপের জন্য java/
ডিরেক্টরি তৈরি করতে:
- প্রকল্পের ফলকটি খুলুন এবং ফলকের শীর্ষে মেনু থেকে প্রকল্পের দৃশ্যটি নির্বাচন করুন।
-
MyProject/app/src/
নেভিগেট করুন। -
src
ডিরেক্টরিটিতে ডান ক্লিক করুন এবং নতুন > ডিরেক্টরি নির্বাচন করুন। - গ্রেডল উত্স সেটগুলির অধীনে মেনু থেকে, সম্পূর্ণ/জাভা নির্বাচন করুন।
- এন্টার টিপুন।
অ্যান্ড্রয়েড স্টুডিও আপনার ডিবাগ বিল্ড টাইপের জন্য একটি উত্স সেট ডিরেক্টরি তৈরি করে এবং তারপরে এর ভিতরে java/
ডিরেক্টরি তৈরি করে। বিকল্পভাবে, অ্যান্ড্রয়েড স্টুডিও যখন আপনি একটি নির্দিষ্ট বিল্ড বৈকল্পের জন্য আপনার প্রকল্পে একটি নতুন ফাইল যুক্ত করেন তখন আপনার জন্য ডিরেক্টরিগুলি তৈরি করতে পারে।
উদাহরণস্বরূপ, আপনার "ডিবাগ" বিল্ড টাইপের জন্য একটি মান এক্সএমএল ফাইল তৈরি করতে:
- প্রজেক্ট ফলকে,
src
ডিরেক্টরিতে ডান ক্লিক করুন এবং নতুন > এক্সএমএল > মান এক্সএমএল ফাইল নির্বাচন করুন। - এক্সএমএল ফাইলের জন্য নাম লিখুন বা ডিফল্ট নাম রাখুন।
- লক্ষ্য উত্স সেটের পাশের মেনু থেকে, ডিবাগ নির্বাচন করুন।
- শেষ ক্লিক করুন.
যেহেতু "ডিবাগ" বিল্ড টাইপটি লক্ষ্য উত্স সেট হিসাবে নির্দিষ্ট করা হয়েছিল, অ্যান্ড্রয়েড স্টুডিও স্বয়ংক্রিয়ভাবে এক্সএমএল ফাইল তৈরি করার সময় প্রয়োজনীয় ডিরেক্টরিগুলি তৈরি করে। ফলস্বরূপ ডিরেক্টরি কাঠামোটি চিত্র 1 এর মতো দেখাচ্ছে।

চিত্র 1। "ডিবাগ" বিল্ড টাইপের জন্য নতুন উত্স সেট ডিরেক্টরি।
সক্রিয় উত্স সেটগুলির আইকনে একটি সবুজ সূচক রয়েছে যাতে তারা সক্রিয় রয়েছে তা দেখানোর জন্য। debug
উত্স সেটটি [main]
এর সাথে প্রত্যয়যুক্ত যে এটি main
উত্স সেটটিতে একীভূত হবে তা দেখানোর জন্য।
একই পদ্ধতি ব্যবহার করে, আপনি src/demo/
মতো পণ্যের স্বাদগুলির জন্য উত্স সেট ডিরেক্টরিগুলিও তৈরি করতে পারেন এবং src/demoDebug/
মতো রূপগুলি তৈরি করতে পারেন। অতিরিক্তভাবে, আপনি টেস্টিং সোর্স সেটগুলি তৈরি করতে পারেন যা নির্দিষ্ট বিল্ড ভেরিয়েন্টগুলি লক্ষ্য করে যেমন src/androidTestDemoDebug/
। আরও জানতে, উত্স সেটগুলি পরীক্ষার বিষয়ে পড়ুন।
ডিফল্ট উত্স সেট কনফিগারেশন পরিবর্তন করুন
আপনার যদি উত্স সেটগুলি তৈরি করার বিষয়ে পূর্ববর্তী বিভাগে বর্ণিত গ্রেডল প্রত্যাশা করে এমন ডিফল্ট উত্স সেট ফাইল কাঠামোর মধ্যে সংগঠিত না এমন উত্স থাকে তবে আপনি উত্স সেটের প্রতিটি উপাদানগুলির জন্য ফাইলগুলি সংগ্রহ করতে দেখছেন যেখানে পরিবর্তন করতে sourceSets
ব্লকটি ব্যবহার করতে পারেন।
sourceSets
ব্লকটি অবশ্যই android
ব্লকে থাকতে হবে। আপনার উত্স ফাইলগুলি স্থানান্তর করার দরকার নেই; মডিউল-লেভেল build.gradle.kts
ফাইলের সাথে সম্পর্কিত আপনাকে কেবল পাথ (গুলি) দিয়ে গ্রেড সরবরাহ করতে হবে, যেখানে গ্রেডল প্রতিটি উত্স সেট উপাদানগুলির জন্য ফাইলগুলি সন্ধান করতে পারে। আপনি কোন উপাদানগুলি কনফিগার করতে পারেন এবং আপনি তাদের একাধিক ফাইল বা ডিরেক্টরিতে মানচিত্র করতে পারেন কিনা তা জানতে, অ্যান্ড্রয়েড গ্রেডল প্লাগইন এপিআই রেফারেন্সটি দেখুন।
নিম্নলিখিত কোড নমুনা মানচিত্রগুলি app/other/
ডিরেক্টরি থেকে main
উত্স সেটের নির্দিষ্ট উপাদানগুলিতে উত্সগুলি এবং androidTest
উত্স সেটটির মূল ডিরেক্টরিটি পরিবর্তন করে:
কোটলিন
android { ... // Encapsulates configurations for the main source set. sourceSets.getByName("main") { // Changes the directory for Java sources. The default directory is // 'src/main/java'. java.setSrcDirs(listOf("other/java")) // If you list multiple directories, Gradle uses all of them to collect // sources. Because Gradle gives these directories equal priority, if // you define the same resource in more than one directory, you receive an // error when merging resources. The default directory is 'src/main/res'. res.setSrcDirs(listOf("other/res1", "other/res2")) // Note: Avoid specifying a directory that is a parent to one // or more other directories you specify. For example, avoid the following: // res.srcDirs = ['other/res1', 'other/res1/layouts', 'other/res1/strings'] // Specify either only the root 'other/res1' directory or only the // nested 'other/res1/layouts' and 'other/res1/strings' directories. // For each source set, you can specify only one Android manifest. // By default, Android Studio creates a manifest for your main source // set in the src/main/ directory. manifest.srcFile("other/AndroidManifest.xml") ... } // Create additional blocks to configure other source sets. sourceSets.getByName("androidTest") { // If all the files for a source set are located under a single root // directory, you can specify that directory using the setRoot property. // When gathering sources for the source set, Gradle looks only in locations // relative to the root directory you specify. For example, after applying the // configuration below for the androidTest source set, Gradle looks for Java // sources only in the src/tests/java/ directory. setRoot("src/tests") ... } } ...
গ্রোভি
android { ... sourceSets { // Encapsulates configurations for the main source set. main { // Changes the directory for Java sources. The default directory is // 'src/main/java'. java.srcDirs = ['other/java'] // If you list multiple directories, Gradle uses all of them to collect // sources. Because Gradle gives these directories equal priority, if // you define the same resource in more than one directory, you receive an // error when merging resources. The default directory is 'src/main/res'. res.srcDirs = ['other/res1', 'other/res2'] // Note: Avoid specifying a directory that is a parent to one // or more other directories you specify. For example, avoid the following: // res.srcDirs = ['other/res1', 'other/res1/layouts', 'other/res1/strings'] // Specify either only the root 'other/res1' directory or only the // nested 'other/res1/layouts' and 'other/res1/strings' directories. // For each source set, you can specify only one Android manifest. // By default, Android Studio creates a manifest for your main source // set in the src/main/ directory. manifest.srcFile 'other/AndroidManifest.xml' ... } // Create additional blocks to configure other source sets. androidTest { // If all the files for a source set are located under a single root // directory, you can specify that directory using the setRoot property. // When gathering sources for the source set, Gradle looks only in locations // relative to the root directory you specify. For example, after applying the // configuration below for the androidTest source set, Gradle looks for Java // sources only in the src/tests/java/ directory. setRoot 'src/tests' ... } } } ...
নোট করুন যে একটি উত্স ডিরেক্টরি কেবল একটি উত্স সেটের অন্তর্ভুক্ত। উদাহরণস্বরূপ, আপনি test
এবং androidTest
উত্স সেট উভয়ের সাথে একই পরীক্ষার উত্সগুলি ভাগ করতে পারবেন না। এটি কারণ অ্যান্ড্রয়েড স্টুডিও প্রতিটি উত্স সেটের জন্য পৃথক ইন্টেলিজ মডিউল তৈরি করে এবং উত্স সেটগুলি জুড়ে সদৃশ সামগ্রীর শিকড়কে সমর্থন করতে পারে না।
উত্স সেট দিয়ে তৈরি করুন
আপনি কেবল নির্দিষ্ট কনফিগারেশন সহ প্যাকেজযুক্ত কোড এবং সংস্থানগুলি ধারণ করতে উত্স সেট ডিরেক্টরিগুলি ব্যবহার করতে পারেন। উদাহরণস্বরূপ, আপনি যদি "ডেমোডেব্যাগ" বিল্ড ভেরিয়েন্টটি তৈরি করছেন, যা একটি "ডেমো" পণ্য স্বাদ এবং "ডিবাগ" বিল্ড টাইপের ক্রসপ্রোডাক্ট, গ্রেডল এই ডিরেক্টরিগুলি দেখে এবং তাদের নিম্নলিখিত অগ্রাধিকার দেয়:
-
src/demoDebug/
(ভেরিয়েন্ট সোর্স সেট তৈরি করুন) -
src/debug/
(বিল্ড টাইপ উত্স সেট) -
src/demo/
(পণ্য স্বাদ উত্স সেট) -
src/main/
(প্রধান উত্স সেট)
পণ্য স্বাদের সংমিশ্রণের জন্য তৈরি উত্স সেটগুলিতে অবশ্যই সমস্ত গন্ধের মাত্রা অন্তর্ভুক্ত করতে হবে। উদাহরণস্বরূপ, বিল্ড বৈকল্পিক উত্স সেটটি অবশ্যই বিল্ড টাইপ এবং সমস্ত গন্ধের মাত্রার সংমিশ্রণ হতে হবে। একাধিক তবে সমস্ত গন্ধের মাত্রা কভার করে না এমন ফোল্ডারগুলির সাথে জড়িত কোড এবং সংস্থানগুলি মার্জ করা সমর্থিত নয়।
আপনি যদি একাধিক পণ্যের স্বাদ একত্রিত করেন তবে পণ্যের স্বাদের মধ্যে অগ্রাধিকারটি তাদের স্বীকৃত গন্ধের মাত্রা দ্বারা নির্ধারিত হয়। android.flavorDimensions
সম্পত্তি দিয়ে গন্ধের মাত্রাগুলি তালিকাভুক্ত করার সময়, আপনার তালিকার প্রথম গন্ধের মাত্রার সাথে সম্পর্কিত পণ্য স্বাদগুলি দ্বিতীয় গন্ধের মাত্রার অন্তর্ভুক্তগুলির চেয়ে বেশি অগ্রাধিকার রয়েছে। অতিরিক্তভাবে, পণ্য স্বাদের সংমিশ্রণের জন্য আপনি তৈরি উত্স সেটগুলি পৃথক পণ্যের স্বাদের সাথে সম্পর্কিত উত্স সেটগুলির চেয়ে বেশি অগ্রাধিকার রয়েছে।
অগ্রাধিকার আদেশটি নির্ধারণ করে যে গ্রেডল কোড এবং সংস্থানগুলি একত্রিত করার সময় কোন উত্স সেটটির উচ্চতর অগ্রাধিকার রয়েছে। যেহেতু demoDebug/
উত্স সেট ডিরেক্টরিটিতে সম্ভবত সেই বিল্ড ভেরিয়েন্টের সাথে সুনির্দিষ্ট ফাইল রয়েছে, যদি demoDebug/
এমন একটি ফাইল অন্তর্ভুক্ত থাকে যা debug/
এও সংজ্ঞায়িত করা হয়, গ্রেডলটি demoDebug/
উত্স সেটে ফাইলটি ব্যবহার করে। একইভাবে, গ্রেডল বিল্ড টাইপে ফাইল দেয় এবং পণ্য স্বাদ উত্সটি main/
একই ফাইলগুলির তুলনায় উচ্চতর অগ্রাধিকার সেট করে। নিম্নলিখিত বিল্ড বিধিগুলি প্রয়োগ করার সময় গ্রেড এই অগ্রাধিকার আদেশটি বিবেচনা করে:
-
kotlin/
বাjava/
ডিরেক্টরিগুলির সমস্ত উত্স কোড একক আউটপুট উত্পন্ন করতে একত্রে সংকলিত হয়।দ্রষ্টব্য: প্রদত্ত বিল্ড বৈকল্পিকের জন্য, গ্রেডলটি একই কোটলিন বা জাভা শ্রেণীর সংজ্ঞায়িত করা দুটি বা ততোধিক উত্স সেট ডিরেক্টরিগুলির মুখোমুখি হলে একটি বিল্ড ত্রুটি ছুড়ে দেয়। উদাহরণস্বরূপ, একটি ডিবাগ অ্যাপ্লিকেশন তৈরি করার সময়, আপনি
src/debug/Utility.kt
এবংsrc/main/Utility.kt
উভয়ই সংজ্ঞায়িত করতে পারবেন না, কারণ গ্রেডল বিল্ড প্রক্রিয়া চলাকালীন এই উভয় ডিরেক্টরি দেখে এবং একটি "সদৃশ শ্রেণি" ত্রুটি ছুঁড়ে দেয়। আপনি যদি বিভিন্ন বিল্ড প্রকারের জন্যUtility.kt
এর বিভিন্ন সংস্করণ চান তবে প্রতিটি বিল্ড টাইপ অবশ্যই ফাইলের নিজস্ব সংস্করণটি সংজ্ঞায়িত করতে হবে এবং এটিmain/
উত্স সেটে অন্তর্ভুক্ত করবে না। - ম্যানিফেস্টগুলি একক ম্যানিফেস্টে একত্রিত হয়। পূর্ববর্তী উদাহরণে তালিকার মতো একই ক্রমে অগ্রাধিকার দেওয়া হয়। এটি হ'ল একটি বিল্ড টাইপের জন্য ম্যানিফেস্ট সেটিংস কোনও পণ্য গন্ধের জন্য ম্যানিফেস্ট সেটিংসকে ওভাররাইড করে এবং আরও অনেক কিছু। আরও জানতে, ম্যানিফেস্ট মার্জিং সম্পর্কে পড়ুন।
-
values/
ডিরেক্টরিগুলিতে ফাইলগুলি একত্রিত হয়। যদি দুটি ফাইলের একই নাম থাকে যেমন দুটিstrings.xml
ফাইল, পূর্ববর্তী উদাহরণে তালিকার মতো একই ক্রমে অগ্রাধিকার দেওয়া হয়। এটি হ'ল, বিল্ড টাইপ উত্সের একটি ফাইলে সংজ্ঞায়িত মানগুলি কোনও পণ্যের স্বাদে একই ফাইলে সংজ্ঞায়িত মানগুলিকে ওভাররাইড করে এবং আরও অনেক কিছু। -
res/
এবংasset/
ডিরেক্টরিগুলির সংস্থানগুলি একসাথে প্যাকেজ করা হয়। যদি দুটি বা ততোধিক উত্স সেটগুলিতে একই নামের সাথে সংজ্ঞায়িত সংস্থানগুলি থাকে তবে পূর্ববর্তী উদাহরণে তালিকার মতো একই ক্রমে অগ্রাধিকার দেওয়া হয়। - গ্রেডল অ্যাপ্লিকেশনটি তৈরি করার সময় লাইব্রেরি মডিউল নির্ভরতাগুলির সাথে অন্তর্ভুক্ত সংস্থানগুলি এবং প্রকাশগুলি দেয়।
নির্ভরতা ঘোষণা করুন
একটি নির্দিষ্ট বিল্ড বৈকল্পিক বা পরীক্ষার উত্স সেটের জন্য নির্ভরতা কনফিগার করতে, Implementation
কীওয়ার্ডের আগে বিল্ড বৈকল্পিক বা পরীক্ষার উত্স সেটটির নামটি উপসর্গ করুন, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে:
কোটলিন
dependencies { // Adds the local "mylibrary" module as a dependency to the "free" flavor. "freeImplementation"(project(":mylibrary")) // Adds a remote binary dependency only for local tests. testImplementation("junit:junit:4.12") // Adds a remote binary dependency only for the instrumented test APK. androidTestImplementation("com.android.support.test.espresso:espresso-core:3.6.1") }
গ্রোভি
dependencies { // Adds the local "mylibrary" module as a dependency to the "free" flavor. freeImplementation project(":mylibrary") // Adds a remote binary dependency only for local tests. testImplementation 'junit:junit:4.12' // Adds a remote binary dependency only for the instrumented test APK. androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.6.1' }
নির্ভরতাগুলি কনফিগার করার বিষয়ে আরও তথ্যের জন্য, বিল্ড নির্ভরতা যুক্ত করুন দেখুন।
বৈকল্পিক-সচেতন নির্ভরতা পরিচালনা ব্যবহার করুন
অ্যান্ড্রয়েড গ্রেডল প্লাগইন 3.0.0.0 এবং উচ্চতর একটি নতুন নির্ভরতা প্রক্রিয়া অন্তর্ভুক্ত করে যা কোনও লাইব্রেরি গ্রহণের সময় স্বয়ংক্রিয়ভাবে বৈকল্পিকগুলির সাথে মেলে। এর অর্থ একটি অ্যাপের debug
বৈকল্পিক স্বয়ংক্রিয়ভাবে একটি লাইব্রেরির debug
বৈকল্পিক ব্যবহার করে এবং আরও অনেক কিছু। স্বাদগুলি ব্যবহার করার সময় এটিও কাজ করে: একটি অ্যাপের freeDebug
বৈকল্পিক একটি লাইব্রেরির freeDebug
বৈকল্পিক গ্রাস করবে।
প্লাগইনটি সঠিকভাবে বৈকল্পিকগুলির সাথে মেলে, আপনাকে নিম্নলিখিত বিভাগে বর্ণিত হিসাবে ম্যাচিং ফ্যালব্যাকগুলি সরবরাহ করতে হবে, এমন উদাহরণগুলির জন্য যেখানে সরাসরি ম্যাচ সম্ভব নয়।
উদাহরণস্বরূপ, ধরুন আপনার অ্যাপ্লিকেশনটি "স্টেজিং" নামক একটি বিল্ড টাইপ কনফিগার করে তবে এর গ্রন্থাগার নির্ভরতাগুলির মধ্যে একটি করে না। প্লাগইন যখন আপনার অ্যাপ্লিকেশনটির "স্টেজিং" সংস্করণটি তৈরি করার চেষ্টা করে, তখন এটি লাইব্রেরির কোন সংস্করণটি ব্যবহার করতে হবে তা জানতে পারবে না এবং আপনি নিম্নলিখিতগুলির মতো একটি ত্রুটি বার্তা দেখতে পাবেন:
Error:Failed to resolve: Could not resolve project :mylibrary. Required by: project :app
বৈকল্পিক মিলের সাথে সম্পর্কিত বিল্ড ত্রুটিগুলি সমাধান করুন
প্লাগইনটিতে ডিএসএল উপাদানগুলি অন্তর্ভুক্ত করে আপনাকে কীভাবে গ্রেডল পরিস্থিতি সমাধান করে তা নিয়ন্ত্রণ করতে সহায়তা করে যেখানে একটি অ্যাপ্লিকেশন এবং নির্ভরতার মধ্যে সরাসরি বৈকল্পিক মিল সম্ভব নয়।
নিম্নলিখিতটি বৈকল্পিক-সচেতন নির্ভরতা ম্যাচিং এবং ডিএসএল বৈশিষ্ট্যগুলি ব্যবহার করে কীভাবে সেগুলি সমাধান করবেন সে সম্পর্কিত বিষয়গুলির একটি তালিকা রয়েছে:আপনার অ্যাপ্লিকেশনটিতে একটি বিল্ড টাইপ অন্তর্ভুক্ত রয়েছে যা একটি লাইব্রেরির নির্ভরতা না করে।
উদাহরণস্বরূপ, আপনার অ্যাপ্লিকেশনটিতে একটি "স্টেজিং" বিল্ড টাইপ অন্তর্ভুক্ত রয়েছে তবে একটি নির্ভরতা কেবল "ডিবাগ" এবং "রিলিজ" বিল্ড প্রকারগুলি অন্তর্ভুক্ত করে।
মনে রাখবেন যে কোনও সমস্যা নেই যখন কোনও লাইব্রেরির নির্ভরতা এমন একটি বিল্ড টাইপ অন্তর্ভুক্ত করে যা আপনার অ্যাপ্লিকেশনটি না করে। এটি কারণ প্লাগইনটি কখনই নির্ভরতা থেকে টাইপ তৈরি করে না।
প্রদত্ত বিল্ড টাইপের জন্য বিকল্প ম্যাচগুলি নির্দিষ্ট করতে
matchingFallbacks
ব্যবহার করুন, যেমন এখানে দেখানো হয়েছে:কোটলিন
// In the app's build.gradle.kts file. android { buildTypes { getByName("debug") {} getByName("release") {} create("staging") { // Specifies a sorted list of fallback build types that the // plugin can try to use when a dependency does not include a // "staging" build type. You may specify as many fallbacks as you // like, and the plugin selects the first build type that's // available in the dependency. matchingFallbacks += listOf("debug", "qa", "release") } } }
গ্রোভি
// In the app's build.gradle file. android { buildTypes { debug {} release {} staging { // Specifies a sorted list of fallback build types that the // plugin can try to use when a dependency does not include a // "staging" build type. You may specify as many fallbacks as you // like, and the plugin selects the first build type that's // available in the dependency. matchingFallbacks = ['debug', 'qa', 'release'] } } }
অ্যাপ্লিকেশন এবং এর লাইব্রেরি নির্ভরতা উভয় ক্ষেত্রেই বিদ্যমান একটি প্রদত্ত গন্ধের মাত্রার জন্য, আপনার অ্যাপ্লিকেশনটিতে লাইব্রেরিটি না এমন স্বাদগুলি অন্তর্ভুক্ত করে।
উদাহরণস্বরূপ, আপনার অ্যাপ্লিকেশন এবং এর লাইব্রেরির নির্ভরতা উভয়ই একটি "স্তর" স্বাদ মাত্রা অন্তর্ভুক্ত করে। তবে অ্যাপটিতে "স্তর" মাত্রায় "ফ্রি" এবং "অর্থ প্রদান" স্বাদ অন্তর্ভুক্ত রয়েছে তবে নির্ভরতার মধ্যে একই মাত্রার জন্য কেবল "ডেমো" এবং "প্রদত্ত" স্বাদ অন্তর্ভুক্ত রয়েছে।
নোট করুন যে অ্যাপ্লিকেশন এবং এর লাইব্রেরির নির্ভরতা উভয় ক্ষেত্রেই বিদ্যমান একটি প্রদত্ত গন্ধের মাত্রার জন্য, কোনও লাইব্রেরিতে কোনও পণ্যের স্বাদ অন্তর্ভুক্ত থাকে যা আপনার অ্যাপ্লিকেশনটি না করে। কারণ প্লাগইনটি কখনই নির্ভরতা থেকে সেই স্বাদটির জন্য অনুরোধ করে না।
অ্যাপের "ফ্রি" পণ্য গন্ধের জন্য বিকল্প ম্যাচগুলি নির্দিষ্ট করতে
matchingFallbacks
ব্যবহার করুন, যেমন এখানে দেখানো হয়েছে:কোটলিন
// In the app's build.gradle.kts file. android { defaultConfig{ // Don't configure matchingFallbacks in the defaultConfig block. // Instead, specify fallbacks for a given product flavor in the // productFlavors block, as shown below. } flavorDimensions += "tier" productFlavors { create("paid") { dimension = "tier" // Because the dependency already includes a "paid" flavor in its // "tier" dimension, you don't need to provide a list of fallbacks // for the "paid" flavor. } create("free") { dimension = "tier" // Specifies a sorted list of fallback flavors that the plugin // can try to use when a dependency's matching dimension does // not include a "free" flavor. Specify as many // fallbacks as you like; the plugin selects the first flavor // that's available in the dependency's "tier" dimension. matchingFallbacks += listOf("demo", "trial") } } }
গ্রোভি
// In the app's build.gradle file. android { defaultConfig{ // Don't configure matchingFallbacks in the defaultConfig block. // Instead, specify fallbacks for a given product flavor in the // productFlavors block, as shown below. } flavorDimensions 'tier' productFlavors { paid { dimension 'tier' // Because the dependency already includes a "paid" flavor in its // "tier" dimension, you don't need to provide a list of fallbacks // for the "paid" flavor. } free { dimension 'tier' // Specifies a sorted list of fallback flavors that the plugin // can try to use when a dependency's matching dimension does // not include a "free" flavor. Specify as many // fallbacks as you like; the plugin selects the first flavor // that's available in the dependency's "tier" dimension. matchingFallbacks = ['demo', 'trial'] } } }
একটি লাইব্রেরির নির্ভরতা একটি স্বাদ মাত্রা অন্তর্ভুক্ত করে যা আপনার অ্যাপ্লিকেশনটি করে না।
উদাহরণস্বরূপ, একটি গ্রন্থাগার নির্ভরতা একটি "মিনাপি" মাত্রার জন্য স্বাদ অন্তর্ভুক্ত করে তবে আপনার অ্যাপ্লিকেশনটিতে কেবলমাত্র "স্তর" মাত্রার জন্য স্বাদ অন্তর্ভুক্ত রয়েছে। আপনি যখন আপনার অ্যাপ্লিকেশনটির "ফ্রিডেবাগ" সংস্করণটি তৈরি করতে চান, তখন প্লাগইনটি "মিনাপি 23 ডিবাগ" বা "মিনাপি 18 ডিবাগ" সংস্করণটি নির্ভরতার ব্যবহার করবেন কিনা তা জানেন না।
মনে রাখবেন যে কোনও সমস্যা নেই যখন আপনার অ্যাপ্লিকেশনটিতে একটি স্বাদের মাত্রা অন্তর্ভুক্ত থাকে যা কোনও লাইব্রেরির নির্ভরতা না করে। কারণ প্লাগইন নির্ভরতার মধ্যে বিদ্যমান মাত্রাগুলির স্বাদের সাথে মেলে। উদাহরণস্বরূপ, যদি কোনও নির্ভরতা এবিআইএসের জন্য কোনও মাত্রা অন্তর্ভুক্ত না করে তবে আপনার অ্যাপ্লিকেশনটির "ফ্রিএক্স 86 ডিবাগ" সংস্করণটি নির্ভরতার "ফ্রিডেবাগ" সংস্করণটি ব্যবহার করবে।
নিম্নলিখিত নমুনায় দেখানো হয়েছে, প্রতিটি অনুপস্থিত মাত্রা থেকে নির্বাচন করতে প্লাগইনটির জন্য ডিফল্ট গন্ধ নির্দিষ্ট করতে
defaultConfig
ব্লকেmissingDimensionStrategy
ব্যবহার করুন। আপনিproductFlavors
ব্লকে আপনার নির্বাচনগুলি ওভাররাইড করতে পারেন, যাতে প্রতিটি স্বাদ অনুপস্থিত মাত্রার জন্য একটি পৃথক মিলের কৌশল নির্দিষ্ট করতে পারে।কোটলিন
// In the app's build.gradle.kts file. android { defaultConfig{ // Specifies a sorted list of flavors that the plugin can try to use from // a given dimension. This tells the plugin to select the "minApi18" flavor // when encountering a dependency that includes a "minApi" dimension. // You can include additional flavor names to provide a // sorted list of fallbacks for the dimension. missingDimensionStrategy("minApi", "minApi18", "minApi23") // Specify a missingDimensionStrategy property for each // dimension that exists in a local dependency but not in your app. missingDimensionStrategy("abi", "x86", "arm64") } flavorDimensions += "tier" productFlavors { create("free") { dimension = "tier" // You can override the default selection at the product flavor // level by configuring another missingDimensionStrategy property // for the "minApi" dimension. missingDimensionStrategy("minApi", "minApi23", "minApi18") } create("paid") {} } }
গ্রোভি
// In the app's build.gradle file. android { defaultConfig{ // Specifies a sorted list of flavors that the plugin can try to use from // a given dimension. This tells the plugin to select the "minApi18" flavor // when encountering a dependency that includes a "minApi" dimension. // You can include additional flavor names to provide a // sorted list of fallbacks for the dimension. missingDimensionStrategy 'minApi', 'minApi18', 'minApi23' // Specify a missingDimensionStrategy property for each // dimension that exists in a local dependency but not in your app. missingDimensionStrategy 'abi', 'x86', 'arm64' } flavorDimensions 'tier' productFlavors { free { dimension 'tier' // You can override the default selection at the product flavor // level by configuring another missingDimensionStrategy property // for the 'minApi' dimension. missingDimensionStrategy 'minApi', 'minApi23', 'minApi18' } paid {} } }
আরও তথ্যের জন্য, অ্যান্ড্রয়েড গ্রেডল প্লাগইন ডিএসএল রেফারেন্সে matchingFallbacks
এবং missingDimensionStrategy
দেখুন।
স্বাক্ষর সেটিংস কনফিগার করুন
গ্রেডল আপনার রিলিজ বিল্ডের এপিকে বা এএবি স্বাক্ষর করে না যদি না আপনি এই বিল্ডের জন্য কোনও স্বাক্ষর কনফিগারেশন স্পষ্টভাবে সংজ্ঞায়িত করেন। আপনার যদি এখনও কোনও স্বাক্ষর কী না থাকে তবে অ্যান্ড্রয়েড স্টুডিও ব্যবহার করে একটি আপলোড কী এবং কীস্টোর তৈরি করুন ।
গ্রেডল বিল্ড কনফিগারেশনগুলি ব্যবহার করে আপনার রিলিজ বিল্ড টাইপের জন্য ম্যানুয়ালি স্বাক্ষর কনফিগারেশনগুলি কনফিগার করতে:
- একটি কীস্টোর তৈরি করুন। একটি কীস্টোর একটি বাইনারি ফাইল যা ব্যক্তিগত কীগুলির একটি সেট রয়েছে। আপনাকে অবশ্যই আপনার কীস্টোরকে একটি নিরাপদ এবং সুরক্ষিত জায়গায় রাখতে হবে।
- একটি ব্যক্তিগত কী তৈরি করুন। বিতরণের জন্য আপনার অ্যাপ্লিকেশনটিতে স্বাক্ষর করতে একটি ব্যক্তিগত কী ব্যবহার করা হয় এবং এটি কখনই অ্যাপের সাথে অন্তর্ভুক্ত হয় না বা অননুমোদিত তৃতীয় পক্ষগুলিতে প্রকাশ করা হয় না।
মডিউল-স্তরের
build.gradle.kts
ফাইলটিতে সাইনিং কনফিগারেশন যুক্ত করুন:কোটলিন
... android { ... defaultConfig {...} signingConfigs { create("release") { storeFile = file("myreleasekey.keystore") storePassword = "password" keyAlias = "MyReleaseKey" keyPassword = "password" } } buildTypes { getByName("release") { ... signingConfig = signingConfigs.getByName("release") } } }
গ্রোভি
... android { ... defaultConfig {...} signingConfigs { release { storeFile file("myreleasekey.keystore") storePassword "password" keyAlias "MyReleaseKey" keyPassword "password" } } buildTypes { release { ... signingConfig signingConfigs.release } } }
দ্রষ্টব্য: আপনার রিলিজ কী এবং বিল্ড ফাইলের অভ্যন্তরে কীস্টোরের পাসওয়ার্ড সহ কোনও ভাল সুরক্ষা অনুশীলন নয়। পরিবর্তে, পরিবেশের ভেরিয়েবলগুলি থেকে এই পাসওয়ার্ডগুলি পেতে বিল্ড ফাইলটি কনফিগার করুন বা বিল্ড প্রক্রিয়া আপনাকে এই পাসওয়ার্ডগুলির জন্য অনুরোধ জানায়।
পরিবেশের ভেরিয়েবলগুলি থেকে এই পাসওয়ার্ডগুলি পেতে:
কোটলিন
storePassword = System.getenv("KSTOREPWD") keyPassword = System.getenv("KEYPWD")
গ্রোভি
storePassword System.getenv("KSTOREPWD") keyPassword System.getenv("KEYPWD")
বিকল্পভাবে, আপনি কোনও স্থানীয় বৈশিষ্ট্য ফাইল থেকে কীস্টোরটি লোড করতে পারেন। সুরক্ষার কারণে, উত্স নিয়ন্ত্রণে এই ফাইলটি যুক্ত করবেন না। পরিবর্তে, প্রতিটি বিকাশকারীর জন্য এটি স্থানীয়ভাবে সেট আপ করুন। আরও জানতে, আপনার বিল্ড ফাইলগুলি থেকে স্বাক্ষর সম্পর্কিত তথ্য সরান পড়ুন।
আপনি এই প্রক্রিয়াটি শেষ করার পরে, আপনি আপনার অ্যাপ্লিকেশন বিতরণ করতে এবং এটি গুগল প্লেতে প্রকাশ করতে পারেন।
সতর্কতা: আপনার কীস্টোর এবং প্রাইভেট কী একটি নিরাপদ এবং সুরক্ষিত জায়গায় রাখুন এবং নিশ্চিত করুন যে আপনার কাছে সেগুলির নিরাপদ ব্যাকআপ আছে। আপনি যদি প্লে অ্যাপ সাইনিং ব্যবহার করেন এবং আপনি আপনার আপলোড কীটি হারাবেন, আপনি প্লে কনসোলটি ব্যবহার করে একটি রিসেটের জন্য অনুরোধ করতে পারেন। আপনি যদি প্লে অ্যাপ সাইন না করে কোনও অ্যাপ্লিকেশন প্রকাশ করছেন (2021 আগস্টের আগে তৈরি অ্যাপ্লিকেশনগুলির জন্য) এবং আপনি আপনার অ্যাপ্লিকেশন সাইনিং কীটি হারাবেন, আপনি আপনার অ্যাপ্লিকেশনটিতে কোনও আপডেট প্রকাশ করতে সক্ষম হবেন না, কারণ আপনাকে অবশ্যই সর্বদা একই কী দিয়ে আপনার অ্যাপ্লিকেশনটির সমস্ত সংস্করণে স্বাক্ষর করতে হবে।
ওএস অ্যাপ্লিকেশন পরিধান করা স্বাক্ষর
ওএস অ্যাপ্লিকেশন পরিধানের সময় প্রকাশের সময়, ওয়াচ এপিকে এবং al চ্ছিক ফোন এপিকে উভয়ই একই কী দিয়ে স্বাক্ষর করতে হবে। প্যাকেজিং এবং সাইন ইন ওয়েয়ার ওএস অ্যাপ্লিকেশন সম্পর্কিত আরও তথ্যের জন্য, প্যাকেজ দেখুন এবং পরিধান অ্যাপ্লিকেশন বিতরণ করুন ।
,এই পৃষ্ঠাটি আপনাকে দেখায় যে আপনি কীভাবে একটি একক প্রকল্প থেকে আপনার অ্যাপ্লিকেশনটির বিভিন্ন সংস্করণ তৈরি করতে বিল্ড ভেরিয়েন্টগুলি কনফিগার করতে পারেন এবং কীভাবে আপনার নির্ভরতা এবং স্বাক্ষর কনফিগারেশনগুলি সঠিকভাবে পরিচালনা করতে পারেন।
প্রতিটি বিল্ড বৈকল্পিক আপনার অ্যাপ্লিকেশনটির একটি আলাদা সংস্করণ উপস্থাপন করে যা আপনি তৈরি করতে পারেন। উদাহরণস্বরূপ, আপনি আপনার অ্যাপ্লিকেশনটির একটি সংস্করণ তৈরি করতে চাইতে পারেন যা সীমিত সামগ্রীর সেট সহ বিনামূল্যে এবং আরও একটি অর্থ প্রদানের সংস্করণ যা আরও অন্তর্ভুক্ত রয়েছে। আপনি আপনার অ্যাপ্লিকেশনটির বিভিন্ন সংস্করণও তৈরি করতে পারেন যা এপিআই স্তর বা অন্যান্য ডিভাইসের পরিবর্তনের উপর ভিত্তি করে বিভিন্ন ডিভাইসগুলিকে লক্ষ্য করে।
বিল্ড ভেরিয়েন্টগুলি হ'ল আপনার বিল্ড প্রকার এবং পণ্যের স্বাদে কনফিগার করা সেটিংস, কোড এবং সংস্থানগুলি একত্রিত করতে বিধিগুলির একটি নির্দিষ্ট সেট ব্যবহার করে গ্রেডের ফলাফল। যদিও আপনি সরাসরি বিল্ড ভেরিয়েন্টগুলি কনফিগার করেন না, আপনি সেগুলি তৈরি করে এমন বিল্ড প্রকার এবং পণ্য স্বাদগুলি কনফিগার করেন।
উদাহরণস্বরূপ, একটি "ডেমো" পণ্য স্বাদ নির্দিষ্ট বৈশিষ্ট্য এবং ডিভাইসের প্রয়োজনীয়তা যেমন কাস্টম উত্স কোড, সংস্থান এবং ন্যূনতম এপিআই স্তরগুলি নির্দিষ্ট করতে পারে, যখন "ডিবাগ" বিল্ড টাইপ বিভিন্ন বিল্ড এবং প্যাকেজিং সেটিংস প্রয়োগ করে যেমন ডিবাগ বিকল্প এবং স্বাক্ষরকারী কীগুলি। এই দুটি সংমিশ্রণকারী বিল্ড ভেরিয়েন্টটি হ'ল আপনার অ্যাপ্লিকেশনটির "ডেমোডেব্যাগ" সংস্করণ এবং এতে "ডেমো" পণ্য স্বাদ, "ডিবাগ" বিল্ড টাইপ এবং main/
উত্স সেট অন্তর্ভুক্ত কনফিগারেশন এবং সংস্থানগুলির সংমিশ্রণ অন্তর্ভুক্ত রয়েছে।
বিল্ড প্রকারগুলি কনফিগার করুন
আপনি মডিউল-লেভেল build.gradle.kts
ফাইলের android
ব্লকের অভ্যন্তরে বিল্ড প্রকারগুলি তৈরি এবং কনফিগার করতে পারেন। আপনি যখন একটি নতুন মডিউল তৈরি করেন, অ্যান্ড্রয়েড স্টুডিও স্বয়ংক্রিয়ভাবে ডিবাগ তৈরি করে এবং বিল্ড প্রকারগুলি প্রকাশ করে। যদিও ডিবাগ বিল্ড টাইপটি বিল্ড কনফিগারেশন ফাইলে উপস্থিত হয় না, অ্যান্ড্রয়েড স্টুডিও এটিকে debuggable true
দিয়ে কনফিগার করে। এটি আপনাকে নিরাপদ অ্যান্ড্রয়েড ডিভাইসে অ্যাপটি ডিবাগ করতে দেয় এবং জেনেরিক ডিবাগ কীস্টোরের সাথে অ্যাপ্লিকেশন সাইনিং কনফিগার করে।
আপনি যদি নির্দিষ্ট সেটিংস যুক্ত করতে বা পরিবর্তন করতে চান তবে আপনি আপনার কনফিগারেশনে ডিবাগ বিল্ড টাইপ যুক্ত করতে পারেন। নিম্নলিখিত নমুনাটি ডিবাগ বিল্ড টাইপের জন্য একটি applicationIdSuffix
নির্দিষ্ট করে এবং একটি "স্টেজিং" বিল্ড টাইপ কনফিগার করে যা ডিবাগ বিল্ড টাইপ থেকে সেটিংস ব্যবহার করে শুরু করা হয়:
কোটলিন
android { defaultConfig { manifestPlaceholders["hostName"] = "www.example.com" ... } buildTypes { getByName("release") { isMinifyEnabled = true proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro") } getByName("debug") { applicationIdSuffix = ".debug" isDebuggable = true } /** * The `initWith` property lets you copy configurations from other build types, * then configure only the settings you want to change. This one copies the debug build * type, and then changes the manifest placeholder and application ID. */ create("staging") { initWith(getByName("debug")) manifestPlaceholders["hostName"] = "internal.example.com" applicationIdSuffix = ".debugStaging" } } }
গ্রোভি
android { defaultConfig { manifestPlaceholders = [hostName:"www.example.com"] ... } buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } debug { applicationIdSuffix ".debug" debuggable true } /** * The `initWith` property lets you copy configurations from other build types, * then configure only the settings you want to change. This one copies the debug build * type, and then changes the manifest placeholder and application ID. */ staging { initWith debug manifestPlaceholders = [hostName:"internal.example.com"] applicationIdSuffix ".debugStaging" } } }
দ্রষ্টব্য: আপনি যখন কোনও বিল্ড কনফিগারেশন ফাইলে পরিবর্তন করেন, অ্যান্ড্রয়েড স্টুডিওর জন্য আপনার প্রকল্পটি নতুন কনফিগারেশনের সাথে সিঙ্ক করার প্রয়োজন। আপনার প্রকল্পটি সিঙ্ক করতে, আপনি যখন কোনও পরিবর্তন করেন বা সিঙ্ক প্রজেক্ট ক্লিক করেন তখন উপস্থিত বিজ্ঞপ্তি বারে এখনই সিঙ্ক ক্লিক করুন টুলবার থেকে। যদি অ্যান্ড্রয়েড স্টুডিও আপনার কনফিগারেশনের সাথে কোনও ত্রুটি লক্ষ্য করে তবে বার্তা উইন্ডোটি সমস্যাটি বর্ণনা করে বলে মনে হয়।
আপনি বিল্ড প্রকারের সাথে কনফিগার করতে পারেন এমন সমস্ত বৈশিষ্ট্য সম্পর্কে আরও জানতে, BuildType
রেফারেন্সটি পড়ুন।
পণ্যের স্বাদগুলি কনফিগার করুন
পণ্যের স্বাদ তৈরি করা বিল্ড প্রকার তৈরির অনুরূপ। আপনার বিল্ড কনফিগারেশনে প্রোডাক্ট productFlavors
ব্লকে পণ্যের স্বাদ যোগ করুন এবং আপনি যে সেটিংস চান তা অন্তর্ভুক্ত করুন। পণ্যের স্বাদগুলি defaultConfig
মতো একই বৈশিষ্ট্যগুলিকে সমর্থন করে, কারণ defaultConfig
আসলে ProductFlavor
শ্রেণীর অন্তর্ভুক্ত। এর অর্থ আপনি defaultConfig
ব্লকের সমস্ত স্বাদের জন্য বেস কনফিগারেশন সরবরাহ করতে পারেন এবং প্রতিটি গন্ধ এই ডিফল্ট মানগুলির যেমন কোনও applicationId
পরিবর্তন করতে পারে। অ্যাপ্লিকেশন আইডি সম্পর্কে আরও জানতে, অ্যাপ্লিকেশন আইডি সেট করুন ।
দ্রষ্টব্য: আপনাকে এখনও main/
ম্যানিফেস্ট ফাইলে package
বৈশিষ্ট্যটি ব্যবহার করে একটি প্যাকেজের নাম নির্দিষ্ট করতে হবে। R
ক্লাসটি উল্লেখ করতে বা কোনও আপেক্ষিক ক্রিয়াকলাপ বা পরিষেবা নিবন্ধকরণ সমাধানের জন্য আপনাকে অবশ্যই সেই প্যাকেজের নামটি আপনার উত্স কোডে ব্যবহার করতে হবে। এটি আপনাকে আপনার উত্স কোডটি পরিবর্তন না করে প্যাকেজিং এবং বিতরণের জন্য প্রতিটি পণ্য স্বাদকে একটি অনন্য আইডি দিতে applicationId
ব্যবহার করতে দেয়।
সমস্ত স্বাদ অবশ্যই একটি নামযুক্ত স্বাদ মাত্রার সাথে সম্পর্কিত, যা পণ্য স্বাদের একটি গ্রুপ। আপনাকে অবশ্যই সমস্ত স্বাদকে স্বাদ মাত্রায় বরাদ্দ করতে হবে; অন্যথায়, আপনি নিম্নলিখিত বিল্ড ত্রুটি পাবেন।
Error: All flavors must now belong to a named flavor dimension. The flavor 'flavor_name' is not assigned to a flavor dimension.
যদি কোনও প্রদত্ত মডিউলটি কেবল একটি স্বাদের মাত্রা নির্দিষ্ট করে তবে অ্যান্ড্রয়েড গ্রেডল প্লাগইন স্বয়ংক্রিয়ভাবে মডিউলটির সমস্ত স্বাদগুলি সেই মাত্রায় বরাদ্দ করে।
নিম্নলিখিত কোড নমুনা "সংস্করণ" নামে একটি স্বাদ মাত্রা তৈরি করে এবং "ডেমো" এবং "পূর্ণ" পণ্য স্বাদ যুক্ত করে। এই স্বাদগুলি তাদের নিজস্ব applicationIdSuffix
এবং versionNameSuffix
সরবরাহ করে:
কোটলিন
android { ... defaultConfig {...} buildTypes { getByName("debug"){...} getByName("release"){...} } // Specifies one flavor dimension. flavorDimensions += "version" productFlavors { create("demo") { // Assigns this product flavor to the "version" flavor dimension. // If you are using only one dimension, this property is optional, // and the plugin automatically assigns all the module's flavors to // that dimension. dimension = "version" applicationIdSuffix = ".demo" versionNameSuffix = "-demo" } create("full") { dimension = "version" applicationIdSuffix = ".full" versionNameSuffix = "-full" } } }
গ্রোভি
android { ... defaultConfig {...} buildTypes { debug{...} release{...} } // Specifies one flavor dimension. flavorDimensions "version" productFlavors { demo { // Assigns this product flavor to the "version" flavor dimension. // If you are using only one dimension, this property is optional, // and the plugin automatically assigns all the module's flavors to // that dimension. dimension "version" applicationIdSuffix ".demo" versionNameSuffix "-demo" } full { dimension "version" applicationIdSuffix ".full" versionNameSuffix "-full" } } }
দ্রষ্টব্য: আপনার যদি কোনও লিগ্যাসি অ্যাপ থাকে (2021 আগস্টের আগে তৈরি) আপনি গুগল প্লেতে এপিকে ব্যবহার করে বিতরণ করেন, গুগল প্লেটিতে একাধিক এপিকে সমর্থন ব্যবহার করে আপনার অ্যাপ্লিকেশন বিতরণ করতে, সমস্ত ভেরিয়েন্টগুলিতে একই applicationId
মান নির্ধারণ করুন এবং প্রতিটি বৈকল্পিককে আলাদা versionCode
দিন। গুগল প্লেতে পৃথক অ্যাপ্লিকেশন হিসাবে আপনার অ্যাপ্লিকেশনটির বিভিন্ন রূপগুলি বিতরণ করতে আপনাকে প্রতিটি বৈকল্পিককে আলাদা applicationId
নির্ধারণ করতে হবে।
আপনি আপনার পণ্যের স্বাদগুলি তৈরি এবং কনফিগার করার পরে, বিজ্ঞপ্তি বারে এখনই সিঙ্ক ক্লিক করুন। একবার সিঙ্কটি শেষ হয়ে গেলে, গ্রেডটি স্বয়ংক্রিয়ভাবে আপনার বিল্ড প্রকার এবং পণ্যের স্বাদের উপর ভিত্তি করে বিল্ড ভেরিয়েন্টগুলি তৈরি করে এবং <product-flavor><Build-Type>
অনুযায়ী তাদের নাম দেয়। উদাহরণস্বরূপ, আপনি যদি "ডেমো" এবং "পূর্ণ" পণ্য স্বাদ তৈরি করেন এবং ডিফল্ট "ডিবাগ" এবং "রিলিজ" বিল্ড প্রকারগুলি রাখেন, গ্রেডল নিম্নলিখিত বিল্ড ভেরিয়েন্টগুলি তৈরি করে:
-
demoDebug
-
demoRelease
-
fullDebug
-
fullRelease
কোন বিল্ড ভেরিয়েন্টটি তৈরি এবং চালানোর জন্য নির্বাচন করতে, বিল্ডে যান> বিল্ড ভেরিয়েন্ট নির্বাচন করুন এবং মেনু থেকে একটি বিল্ড ভেরিয়েন্ট নির্বাচন করুন। প্রতিটি বিল্ড ভেরিয়েন্টকে তার নিজস্ব বৈশিষ্ট্য এবং সংস্থানগুলির সাথে কাস্টমাইজ করা শুরু করতে, আপনাকে এই পৃষ্ঠায় বর্ণিত হিসাবে উত্স সেটগুলি তৈরি এবং পরিচালনা করতে হবে।
বিল্ড ভেরিয়েন্টগুলির জন্য অ্যাপ্লিকেশন আইডি পরিবর্তন করুন
আপনি যখন আপনার অ্যাপ্লিকেশনটির জন্য একটি APK বা AAB তৈরি করেন, বিল্ড সরঞ্জামগুলি build.gradle.kts
ফাইল থেকে defaultConfig
ব্লকে সংজ্ঞায়িত অ্যাপ্লিকেশন আইডি সহ অ্যাপ্লিকেশনটিকে ট্যাগ করে, নিম্নলিখিত উদাহরণে দেখানো হয়েছে। তবে, আপনি যদি গুগল প্লে স্টোরে পৃথক তালিকা হিসাবে উপস্থিত হওয়ার জন্য আপনার অ্যাপ্লিকেশনটির বিভিন্ন সংস্করণ তৈরি করতে চান, যেমন একটি "ফ্রি" এবং "প্রো" সংস্করণ, আপনাকে পৃথক বিল্ড ভেরিয়েন্ট তৈরি করতে হবে যা প্রত্যেকের আলাদা অ্যাপ্লিকেশন আইডি রয়েছে।
এই ক্ষেত্রে, প্রতিটি বিল্ড বৈকল্পিককে পৃথক পণ্য স্বাদ হিসাবে সংজ্ঞায়িত করুন। productFlavors
ব্লকের অভ্যন্তরের প্রতিটি গন্ধের জন্য, আপনি applicationId
সম্পত্তিটি নতুন করে সংজ্ঞায়িত করতে পারেন, বা পরিবর্তে আপনি এখানে দেখানো হিসাবে applicationIdSuffix
ব্যবহার করে ডিফল্ট অ্যাপ্লিকেশন আইডিতে একটি বিভাগ সংযোজন করতে পারেন:
কোটলিন
android { defaultConfig { applicationId = "com.example.myapp" } productFlavors { create("free") { applicationIdSuffix = ".free" } create("pro") { applicationIdSuffix = ".pro" } } }
গ্রোভি
android { defaultConfig { applicationId "com.example.myapp" } productFlavors { free { applicationIdSuffix ".free" } pro { applicationIdSuffix ".pro" } } }
এইভাবে, "ফ্রি" পণ্য গন্ধের জন্য অ্যাপ্লিকেশন আইডি হ'ল "com.example.myapp.free"।
আপনি এখানে দেখানো হিসাবে আপনার বিল্ড টাইপের উপর ভিত্তি করে একটি বিভাগ সংযোজন করতে applicationIdSuffix
ব্যবহার করতে পারেন:
কোটলিন
android { ... buildTypes { getByName("debug") { applicationIdSuffix = ".debug" } } }
গ্রোভি
android { ... buildTypes { debug { applicationIdSuffix ".debug" } } }
যেহেতু গ্রেডল পণ্যের স্বাদের পরে বিল্ড টাইপ কনফিগারেশন প্রয়োগ করে, "ফ্রি ডিবাগ" বিল্ড ভেরিয়েন্টের জন্য অ্যাপ্লিকেশন আইডি "com.example.myapp.free.debug"। আপনি যখন একই ডিভাইসে ডিবাগ এবং রিলিজ উভয়ই তৈরি করতে চান তখন এটি কার্যকর, কারণ কোনও দুটি অ্যাপ্লিকেশন একই অ্যাপ্লিকেশন আইডি থাকতে পারে না।
আপনার যদি কোনও লিগ্যাসি অ্যাপ থাকে (2021 আগস্টের আগে তৈরি) আপনি গুগল প্লেতে এপিকে ব্যবহার করে বিতরণ করেন এবং আপনি একই অ্যাপ্লিকেশন তালিকাটি একাধিক এপিকে বিতরণ করতে ব্যবহার করতে চান যা প্রতিটি এপিআই স্তরের মতো আলাদা ডিভাইস কনফিগারেশনকে লক্ষ্য করে, তবে আপনাকে অবশ্যই প্রতিটি বিল্ড ভেরিয়েন্টের জন্য একই অ্যাপ্লিকেশন আইডি ব্যবহার করতে হবে তবে প্রতিটি এপিকে একটি আলাদাversionCode
দিতে হবে। আরও তথ্যের জন্য, একাধিক এপিকে সমর্থন সম্পর্কে পড়ুন। এএবিএস ব্যবহার করে প্রকাশনা প্রভাবিত হয় না, কারণ এটি একটি একক নিদর্শন ব্যবহার করে যা ডিফল্টরূপে একক সংস্করণ কোড এবং অ্যাপ্লিকেশন আইডি ব্যবহার করে। টিপ: আপনার যদি আপনার ম্যানিফেস্ট ফাইলে অ্যাপ্লিকেশন আইডিটি উল্লেখ করতে হয় তবে আপনি কোনও ম্যানিফেস্ট অ্যাট্রিবিউটে ${applicationId}
স্থানধারক ব্যবহার করতে পারেন। একটি বিল্ড চলাকালীন, গ্রেড এই ট্যাগটি প্রকৃত অ্যাপ্লিকেশন আইডি দিয়ে প্রতিস্থাপন করে। আরও তথ্যের জন্য, ম্যানিফেস্টে ইনজেক্ট বিল্ড ভেরিয়েবলগুলি দেখুন।
গন্ধ মাত্রা সঙ্গে একাধিক পণ্য স্বাদ একত্রিত
কিছু ক্ষেত্রে, আপনি একাধিক পণ্য স্বাদ থেকে কনফিগারেশনগুলি একত্রিত করতে চাইতে পারেন। উদাহরণস্বরূপ, আপনি এপিআই স্তরের উপর ভিত্তি করে "পূর্ণ" এবং "ডেমো" পণ্য স্বাদের জন্য বিভিন্ন কনফিগারেশন তৈরি করতে চাইতে পারেন। এটি করার জন্য, অ্যান্ড্রয়েড গ্রেডল প্লাগইন আপনাকে স্বাদের মাত্রা হিসাবে পণ্য স্বাদের একাধিক গ্রুপ তৈরি করতে দেয়।
আপনার অ্যাপ তৈরি করার সময়, গ্রেডল চূড়ান্ত বিল্ড বৈকল্পিক তৈরি করতে বিল্ড টাইপ কনফিগারেশনের সাথে আপনার সংজ্ঞায়িত প্রতিটি ফ্লেভার ডাইমেনশন থেকে একটি প্রোডাক্ট ফ্লেভার কনফিগারেশন একত্রিত করে। গ্রেডল একই স্বাদ মাত্রার সাথে সম্পর্কিত পণ্যের স্বাদগুলিকে একত্রিত করে না।
নিম্নলিখিত কোড নমুনাটি "সম্পূর্ণ" এবং "ডেমো" পণ্যের স্বাদ এবং এপিআই স্তরের উপর ভিত্তি করে গ্রুপ পণ্য স্বাদ কনফিগারেশনের একটি "এপিআই" গন্ধের মাত্রা গ্রুপ করতে একটি "মোড" গন্ধের মাত্রা তৈরি করতে flavorDimensions
সম্পত্তি ব্যবহার করে:
কোটলিন
android { ... buildTypes { getByName("debug") {...} getByName("release") {...} } // Specifies the flavor dimensions you want to use. The order in which you // list the dimensions determines their priority, from highest to lowest, // when Gradle merges variant sources and configurations. You must assign // each product flavor you configure to one of the flavor dimensions. flavorDimensions += listOf("api", "mode") productFlavors { create("demo") { // Assigns this product flavor to the "mode" flavor dimension. dimension = "mode" ... } create("full") { dimension = "mode" ... } // Configurations in the "api" product flavors override those in "mode" // flavors and the defaultConfig block. Gradle determines the priority // between flavor dimensions based on the order in which they appear next // to the flavorDimensions property, with the first dimension having a higher // priority than the second, and so on. create("minApi24") { dimension = "api" minSdk = 24 // To ensure the target device receives the version of the app with // the highest compatible API level, assign version codes in increasing // value with API level. versionCode = 30000 + (android.defaultConfig.versionCode ?: 0) versionNameSuffix = "-minApi24" ... } create("minApi23") { dimension = "api" minSdk = 23 versionCode = 20000 + (android.defaultConfig.versionCode ?: 0) versionNameSuffix = "-minApi23" ... } create("minApi21") { dimension = "api" minSdk = 21 versionCode = 10000 + (android.defaultConfig.versionCode ?: 0) versionNameSuffix = "-minApi21" ... } } } ...
গ্রোভি
android { ... buildTypes { debug {...} release {...} } // Specifies the flavor dimensions you want to use. The order in which you // list the dimensions determines their priority, from highest to lowest, // when Gradle merges variant sources and configurations. You must assign // each product flavor you configure to one of the flavor dimensions. flavorDimensions "api", "mode" productFlavors { demo { // Assigns this product flavor to the "mode" flavor dimension. dimension "mode" ... } full { dimension "mode" ... } // Configurations in the "api" product flavors override those in "mode" // flavors and the defaultConfig block. Gradle determines the priority // between flavor dimensions based on the order in which they appear next // to the flavorDimensions property, with the first dimension having a higher // priority than the second, and so on. minApi24 { dimension "api" minSdkVersion 24 // To ensure the target device receives the version of the app with // the highest compatible API level, assign version codes in increasing // value with API level. versionCode 30000 + android.defaultConfig.versionCode versionNameSuffix "-minApi24" ... } minApi23 { dimension "api" minSdkVersion 23 versionCode 20000 + android.defaultConfig.versionCode versionNameSuffix "-minApi23" ... } minApi21 { dimension "api" minSdkVersion 21 versionCode 10000 + android.defaultConfig.versionCode versionNameSuffix "-minApi21" ... } } } ...
গ্রেডল তৈরি করে বিল্ড ভেরিয়েন্টগুলির সংখ্যা প্রতিটি গন্ধের মাত্রায় স্বাদের সংখ্যার পণ্য এবং আপনার কনফিগার করা বিল্ড ধরণের সংখ্যার সমান। যখন গ্রেডের নাম প্রতিটি বিল্ড বৈকল্পিক বা সংশ্লিষ্ট শিল্পকর্মগুলি তৈরি করে, উচ্চ-অগ্রাধিকারের স্বাদ মাত্রার সাথে সম্পর্কিত পণ্যের স্বাদগুলি প্রথমে উপস্থিত হয়, তারপরে নিম্ন-অগ্রাধিকারের মাত্রাগুলি থেকে শুরু করে, তারপরে বিল্ড টাইপ হয়।
উদাহরণ হিসাবে পূর্ববর্তী বিল্ড কনফিগারেশনটি ব্যবহার করে, গ্রেডল নিম্নলিখিত নামকরণ স্কিম সহ মোট 12 টি বিল্ড ভেরিয়েন্ট তৈরি করে:
- বিল্ড ভেরিয়েন্ট:
[minApi24, minApi23, minApi21][Demo, Full][Debug, Release]
- সংশ্লিষ্ট এপিকে:
app-[minApi24, minApi23, minApi21]-[demo, full]-[debug, release].apk
- যেমন,
- বিল্ড ভেরিয়েন্ট:
minApi24DemoDebug
- সংশ্লিষ্ট এপিকে:
app-minApi24-demo-debug.apk
উত্স সেট ডিরেক্টরিগুলি ছাড়াও আপনি প্রতিটি পৃথক পণ্য গন্ধের জন্য তৈরি করতে পারেন এবং বৈকল্পিক তৈরি করতে পারেন, আপনি পণ্যের স্বাদের প্রতিটি সংমিশ্রণের জন্য উত্স সেট ডিরেক্টরিও তৈরি করতে পারেন। উদাহরণস্বরূপ, আপনি src/demoMinApi24/java/
ডিরেক্টরিতে জাভা উত্সগুলি তৈরি এবং যুক্ত করতে পারেন এবং গ্রেডল কেবল তখনই সেই উত্সগুলি ব্যবহার করে যখন এই দুটি পণ্য স্বাদকে একত্রিত করে এমন একটি বৈকল্পিক তৈরি করে।
পণ্য স্বাদ সংমিশ্রণের জন্য আপনার তৈরি উত্স সেটগুলি প্রতিটি পৃথক পণ্যের স্বাদের অন্তর্ভুক্ত উত্স সেটগুলির চেয়ে বেশি অগ্রাধিকার রয়েছে। উত্স সেটগুলি এবং কীভাবে গ্রেডল সংস্থানগুলি একীভূত করে সে সম্পর্কে আরও জানতে, উত্স সেটগুলি কীভাবে তৈরি করবেন সে সম্পর্কে বিভাগটি পড়ুন।
ফিল্টার বৈকল্পিক
Gradle আপনার কনফিগার করা পণ্যের স্বাদ এবং বিল্ড প্রকারের প্রতিটি সম্ভাব্য সমন্বয়ের জন্য একটি বিল্ড বৈকল্পিক তৈরি করে। তবে, এমন কিছু বিল্ড ভেরিয়েন্ট থাকতে পারে যা আপনার প্রয়োজন নেই বা আপনার প্রকল্পের প্রসঙ্গে এটি বোঝায় না। নির্দিষ্ট বিল্ড ভেরিয়েন্ট কনফিগারেশনগুলি অপসারণ করতে, আপনার মডিউল-স্তর build.gradle.kts
ফাইলটিতে একটি বৈকল্পিক ফিল্টার তৈরি করুন।
উদাহরণ হিসাবে পূর্ববর্তী বিভাগ থেকে বিল্ড কনফিগারেশনটি ব্যবহার করে, ধরুন আপনি অ্যাপ্লিকেশনটির ডেমো সংস্করণের জন্য কেবল এপিআই স্তর 23 এবং উচ্চতর সমর্থন করার পরিকল্পনা করছেন। "মিনাপি 21" এবং "ডেমো" পণ্য স্বাদগুলি একত্রিত করে এমন সমস্ত বিল্ড ভেরিয়েন্ট কনফিগারেশনগুলি ফিল্টার করতে আপনি variantFilter
ব্লকটি ব্যবহার করতে পারেন:
কোটলিন
android { ... buildTypes {...} flavorDimensions += listOf("api", "mode") productFlavors { create("demo") {...} create("full") {...} create("minApi24") {...} create("minApi23") {...} create("minApi21") {...} } } androidComponents { beforeVariants { variantBuilder -> // To check for a certain build type, use variantBuilder.buildType == "<buildType>" if (variantBuilder.productFlavors.containsAll(listOf("api" to "minApi21", "mode" to "demo"))) { // Gradle ignores any variants that satisfy the conditions above. variantBuilder.enable = false } } } ...
গ্রোভি
android { ... buildTypes {...} flavorDimensions "api", "mode" productFlavors { demo {...} full {...} minApi24 {...} minApi23 {...} minApi21 {...} } variantFilter { variant -> def names = variant.flavors*.name // To check for a certain build type, use variant.buildType.name == "<buildType>" if (names.contains("minApi21") && names.contains("demo")) { // Gradle ignores any variants that satisfy the conditions above. setIgnore(true) } } } ...
একবার আপনি আপনার বিল্ড কনফিগারেশনে একটি বৈকল্পিক ফিল্টার যুক্ত করার পরে এবং বিজ্ঞপ্তি বারে এখনই সিঙ্ক ক্লিক করুন, গ্রেডল আপনার নির্দিষ্ট শর্তগুলি পূরণ করে এমন কোনও বিল্ড বৈকল্পগুলি উপেক্ষা করে। আপনি যখন বিল্ড> মেনু বার থেকে বিল্ড ভেরিয়েন্ট নির্বাচন করুন বা ভেরিয়েন্টগুলি তৈরি করবেন তখন বিল্ড ভেরিয়েন্টগুলি মেনুতে আর উপস্থিত হয় না সরঞ্জাম উইন্ডো বারে।
সোর্স সেট তৈরি করুন
ডিফল্টরূপে, অ্যান্ড্রয়েড স্টুডিও আপনার সমস্ত বিল্ড ভেরিয়েন্টের মধ্যে শেয়ার করতে চান এমন সবকিছুর জন্য main/
উৎস সেট এবং ডিরেক্টরি তৈরি করে। তবে, নির্দিষ্ট বিল্ড প্রকার, পণ্যের স্বাদ, পণ্যের স্বাদের সংমিশ্রণগুলি ( স্বাদের মাত্রা ব্যবহার করার সময়) এবং রূপগুলি তৈরি করার জন্য কোন ফাইলগুলি গ্রেডল সংকলন এবং প্যাকেজগুলি ঠিক তা নিয়ন্ত্রণ করতে আপনি নতুন উত্স সেট তৈরি করতে পারেন।
উদাহরণস্বরূপ, আপনি main/
উৎস সেটে মৌলিক কার্যকারিতা নির্ধারণ করতে পারেন এবং বিভিন্ন ক্লায়েন্টের জন্য আপনার অ্যাপের ব্র্যান্ডিং পরিবর্তন করতে পণ্যের স্বাদের উৎস সেট ব্যবহার করতে পারেন, অথবা শুধুমাত্র ডিবাগ বিল্ড টাইপ ব্যবহার করে এমন বিল্ড ভেরিয়েন্টের জন্য বিশেষ অনুমতি এবং লগিং কার্যকারিতা অন্তর্ভুক্ত করতে পারেন।
গ্রেডল আশা করে যে উত্স সেট ফাইল এবং ডিরেক্টরিগুলি একটি নির্দিষ্ট উপায়ে সংগঠিত হবে, main/
উত্স সেটের মতো। উদাহরণস্বরূপ, গ্রেডল আপনার "ডিবাগ" বিল্ড টাইপের সাথে সুনির্দিষ্ট যেগুলি src/debug/kotlin/
বা src/debug/java/
ডিরেক্টরিতে অবস্থিত তা নির্দিষ্ট কোটলিন বা জাভা ক্লাস ফাইলগুলি প্রত্যাশা করে।
অ্যান্ড্রয়েড গ্রেডল প্লাগইন একটি দরকারী গ্রেডল টাস্ক সরবরাহ করে যা আপনাকে দেখায় যে কীভাবে আপনার প্রতিটি বিল্ড প্রকার, পণ্যের স্বাদ এবং রূপগুলি তৈরি করার জন্য আপনার ফাইলগুলি কীভাবে সংগঠিত করতে হয়। উদাহরণস্বরূপ, টাস্ক আউটপুট থেকে নিম্নলিখিত নমুনাটি বর্ণনা করে যেখানে গ্রেডল "ডিবাগ" বিল্ড টাইপের জন্য নির্দিষ্ট ফাইলগুলি খুঁজে পাওয়ার প্রত্যাশা করে:
------------------------------------------------------------ Project :app ------------------------------------------------------------ ... debug ---- Compile configuration: debugCompile build.gradle name: android.sourceSets.debug Java sources: [app/src/debug/java] Kotlin sources: [app/src/debug/kotlin, app/src/debug/java] Manifest file: app/src/debug/AndroidManifest.xml Android resources: [app/src/debug/res] Assets: [app/src/debug/assets] AIDL sources: [app/src/debug/aidl] RenderScript sources: [app/src/debug/rs] JNI sources: [app/src/debug/jni] JNI libraries: [app/src/debug/jniLibs] Java-style resources: [app/src/debug/resources]
এই আউটপুটটি দেখতে, নিম্নলিখিত হিসাবে এগিয়ে যান:
- সরঞ্জাম উইন্ডো বারে গ্রেড ক্লিক করুন।
মাই অ্যাপ্লিকেশন> টাস্কস> অ্যান্ড্রয়েড এবং ডাবল-ক্লিক উত্সগুলিতে নেভিগেট করুন।
টাস্ক ফোল্ডারটি দেখতে, আপনাকে অবশ্যই সিঙ্কের সময় গ্রেডলকে টাস্ক তালিকাটি তৈরি করতে হবে। এটি করতে, এই পদক্ষেপগুলি অনুসরণ করুন:
- ফাইল> সেটিংস> পরীক্ষামূলক ( অ্যান্ড্রয়েড স্টুডিও> সেটিংস> ম্যাকোসে পরীক্ষামূলক ) ক্লিক করুন।
- নির্বাসন গ্রেড সিঙ্কের সময় গ্রেডল টাস্ক তালিকা তৈরি করবেন না ।
- গ্রেডল টাস্কটি কার্যকর করার পরে, রান উইন্ডোটি আউটপুটটি প্রদর্শন করতে খোলে।
দ্রষ্টব্য: টাস্ক আউটপুটটি আপনাকে দেখায় যে কীভাবে আপনার অ্যাপ্লিকেশনটির জন্য পরীক্ষা চালানোর জন্য আপনি যে ফাইলগুলি ব্যবহার করতে চান তার জন্য উত্স সেটগুলি কীভাবে সংগঠিত করবেন, যেমন test/
এবং androidTest/
পরীক্ষার উত্স সেটগুলি ।
আপনি যখন একটি নতুন বিল্ড ভেরিয়েন্ট তৈরি করেন, তখন অ্যান্ড্রয়েড স্টুডিও আপনার জন্য সোর্স সেট ডিরেক্টরি তৈরি করে না, তবে এটি আপনাকে সাহায্য করার জন্য কয়েকটি বিকল্প দেয়। উদাহরণস্বরূপ, আপনার "ডিবাগ" বিল্ড টাইপের জন্য java/
ডিরেক্টরি তৈরি করতে:
- প্রকল্পের ফলকটি খুলুন এবং ফলকের শীর্ষে মেনু থেকে প্রকল্পের দৃশ্যটি নির্বাচন করুন।
-
MyProject/app/src/
নেভিগেট করুন। -
src
ডিরেক্টরিটিতে ডান ক্লিক করুন এবং নতুন > ডিরেক্টরি নির্বাচন করুন। - গ্রেডল উত্স সেটগুলির অধীনে মেনু থেকে, সম্পূর্ণ/জাভা নির্বাচন করুন।
- এন্টার টিপুন।
অ্যান্ড্রয়েড স্টুডিও আপনার ডিবাগ বিল্ড টাইপের জন্য একটি উত্স সেট ডিরেক্টরি তৈরি করে এবং তারপরে এর ভিতরে java/
ডিরেক্টরি তৈরি করে। বিকল্পভাবে, অ্যান্ড্রয়েড স্টুডিও যখন আপনি একটি নির্দিষ্ট বিল্ড বৈকল্পের জন্য আপনার প্রকল্পে একটি নতুন ফাইল যুক্ত করেন তখন আপনার জন্য ডিরেক্টরিগুলি তৈরি করতে পারে।
উদাহরণস্বরূপ, আপনার "ডিবাগ" বিল্ড টাইপের জন্য একটি মান এক্সএমএল ফাইল তৈরি করতে:
- প্রজেক্ট ফলকে,
src
ডিরেক্টরিতে ডান ক্লিক করুন এবং নতুন > এক্সএমএল > মান এক্সএমএল ফাইল নির্বাচন করুন। - এক্সএমএল ফাইলের জন্য নাম লিখুন বা ডিফল্ট নাম রাখুন।
- লক্ষ্য উত্স সেটের পাশের মেনু থেকে, ডিবাগ নির্বাচন করুন।
- শেষ ক্লিক করুন.
যেহেতু "ডিবাগ" বিল্ড টাইপটি লক্ষ্য উত্স সেট হিসাবে নির্দিষ্ট করা হয়েছিল, অ্যান্ড্রয়েড স্টুডিও স্বয়ংক্রিয়ভাবে এক্সএমএল ফাইল তৈরি করার সময় প্রয়োজনীয় ডিরেক্টরিগুলি তৈরি করে। ফলস্বরূপ ডিরেক্টরি কাঠামোটি চিত্র 1 এর মতো দেখাচ্ছে।

চিত্র 1। "ডিবাগ" বিল্ড টাইপের জন্য নতুন উত্স সেট ডিরেক্টরি।
সক্রিয় উত্স সেটগুলির আইকনে একটি সবুজ সূচক রয়েছে যাতে তারা সক্রিয় রয়েছে তা দেখানোর জন্য। debug
উত্স সেটটি [main]
এর সাথে প্রত্যয়যুক্ত যে এটি main
উত্স সেটটিতে একীভূত হবে তা দেখানোর জন্য।
একই পদ্ধতি ব্যবহার করে, আপনি src/demo/
মতো পণ্যের স্বাদগুলির জন্য উত্স সেট ডিরেক্টরিগুলিও তৈরি করতে পারেন এবং src/demoDebug/
মতো রূপগুলি তৈরি করতে পারেন। অতিরিক্তভাবে, আপনি টেস্টিং সোর্স সেটগুলি তৈরি করতে পারেন যা নির্দিষ্ট বিল্ড ভেরিয়েন্টগুলি লক্ষ্য করে যেমন src/androidTestDemoDebug/
। আরও জানতে, উত্স সেটগুলি পরীক্ষার বিষয়ে পড়ুন।
ডিফল্ট উত্স সেট কনফিগারেশন পরিবর্তন করুন
আপনার যদি উত্স সেটগুলি তৈরি করার বিষয়ে পূর্ববর্তী বিভাগে বর্ণিত গ্রেডল প্রত্যাশা করে এমন ডিফল্ট উত্স সেট ফাইল কাঠামোর মধ্যে সংগঠিত না এমন উত্স থাকে তবে আপনি উত্স সেটের প্রতিটি উপাদানগুলির জন্য ফাইলগুলি সংগ্রহ করতে দেখছেন যেখানে পরিবর্তন করতে sourceSets
ব্লকটি ব্যবহার করতে পারেন।
sourceSets
ব্লকটি অবশ্যই android
ব্লকে থাকতে হবে। আপনার উত্স ফাইলগুলি স্থানান্তর করার দরকার নেই; মডিউল-লেভেল build.gradle.kts
ফাইলের সাথে সম্পর্কিত আপনাকে কেবল পাথ (গুলি) দিয়ে গ্রেড সরবরাহ করতে হবে, যেখানে গ্রেডল প্রতিটি উত্স সেট উপাদানগুলির জন্য ফাইলগুলি সন্ধান করতে পারে। আপনি কোন উপাদানগুলি কনফিগার করতে পারেন এবং আপনি তাদের একাধিক ফাইল বা ডিরেক্টরিতে মানচিত্র করতে পারেন কিনা তা জানতে, অ্যান্ড্রয়েড গ্রেডল প্লাগইন এপিআই রেফারেন্সটি দেখুন।
The following code sample maps sources from the app/other/
directory to certain components of the main
source set and changes the root directory of the androidTest
source set:
কোটলিন
android { ... // Encapsulates configurations for the main source set. sourceSets.getByName("main") { // Changes the directory for Java sources. The default directory is // 'src/main/java'. java.setSrcDirs(listOf("other/java")) // If you list multiple directories, Gradle uses all of them to collect // sources. Because Gradle gives these directories equal priority, if // you define the same resource in more than one directory, you receive an // error when merging resources. The default directory is 'src/main/res'. res.setSrcDirs(listOf("other/res1", "other/res2")) // Note: Avoid specifying a directory that is a parent to one // or more other directories you specify. For example, avoid the following: // res.srcDirs = ['other/res1', 'other/res1/layouts', 'other/res1/strings'] // Specify either only the root 'other/res1' directory or only the // nested 'other/res1/layouts' and 'other/res1/strings' directories. // For each source set, you can specify only one Android manifest. // By default, Android Studio creates a manifest for your main source // set in the src/main/ directory. manifest.srcFile("other/AndroidManifest.xml") ... } // Create additional blocks to configure other source sets. sourceSets.getByName("androidTest") { // If all the files for a source set are located under a single root // directory, you can specify that directory using the setRoot property. // When gathering sources for the source set, Gradle looks only in locations // relative to the root directory you specify. For example, after applying the // configuration below for the androidTest source set, Gradle looks for Java // sources only in the src/tests/java/ directory. setRoot("src/tests") ... } } ...
গ্রোভি
android { ... sourceSets { // Encapsulates configurations for the main source set. main { // Changes the directory for Java sources. The default directory is // 'src/main/java'. java.srcDirs = ['other/java'] // If you list multiple directories, Gradle uses all of them to collect // sources. Because Gradle gives these directories equal priority, if // you define the same resource in more than one directory, you receive an // error when merging resources. The default directory is 'src/main/res'. res.srcDirs = ['other/res1', 'other/res2'] // Note: Avoid specifying a directory that is a parent to one // or more other directories you specify. For example, avoid the following: // res.srcDirs = ['other/res1', 'other/res1/layouts', 'other/res1/strings'] // Specify either only the root 'other/res1' directory or only the // nested 'other/res1/layouts' and 'other/res1/strings' directories. // For each source set, you can specify only one Android manifest. // By default, Android Studio creates a manifest for your main source // set in the src/main/ directory. manifest.srcFile 'other/AndroidManifest.xml' ... } // Create additional blocks to configure other source sets. androidTest { // If all the files for a source set are located under a single root // directory, you can specify that directory using the setRoot property. // When gathering sources for the source set, Gradle looks only in locations // relative to the root directory you specify. For example, after applying the // configuration below for the androidTest source set, Gradle looks for Java // sources only in the src/tests/java/ directory. setRoot 'src/tests' ... } } } ...
Note that a source directory can only belong to one source set. For example, you can't share the same test sources with both the test
and androidTest
source sets. This is because Android Studio creates separate IntelliJ modules for each source set and can't support duplicate content roots across source sets.
Build with source sets
You can use source set directories to contain the code and resources you want packaged only with certain configurations. For example, if you are building the "demoDebug" build variant, which is the crossproduct of a "demo" product flavor and "debug" build type, Gradle looks at these directories and gives them the following priority:
-
src/demoDebug/
(build variant source set) -
src/debug/
(build type source set) -
src/demo/
(product flavor source set) -
src/main/
(main source set)
Source sets created for combinations of product flavors must include all flavor dimensions. For example, the build variant source set must be the combination of the build type and all flavor dimensions. Merging code and resources involving folders that cover multiple but not all flavor dimensions is not supported.
If you combine multiple product flavors , priority between the product flavors is determined by the flavor dimension they belong to. When listing flavor dimensions with the android.flavorDimensions
property, product flavors that belong to the first flavor dimension you list have a higher priority than those belonging to the second flavor dimension, and so on. Additionally, source sets you create for combinations of product flavors have a higher priority than source sets that belong to an individual product flavor.
The priority order determines which source set has a higher priority when Gradle combines code and resources. Because the demoDebug/
source set directory likely contains files that are specific to that build variant, if demoDebug/
includes a file that is also defined in debug/
, Gradle uses the file in the demoDebug/
source set. Similarly, Gradle gives files in the build type and product flavor source sets a higher priority than the same files in main/
. Gradle considers this priority order when applying the following build rules:
- All source code in the
kotlin/
orjava/
directories are compiled together to generate a single output.Note: For a given build variant, Gradle throws a build error if it encounters two or more source set directories that have defined the same Kotlin or Java class. For example, when building a debug app, you can't define both
src/debug/Utility.kt
andsrc/main/Utility.kt
, because Gradle looks at both these directories during the build process and throws a "duplicate class" error. If you want different versions ofUtility.kt
for different build types, each build type must define its own version of the file and not include it in themain/
source set. - Manifests are merged together into a single manifest. Priority is given in the same order as the list in the previous example. That is, manifest settings for a build type override the manifest settings for a product flavor, and so on. To learn more, read about manifest merging .
- Files in the
values/
directories are merged together. If two files have the same name, such as twostrings.xml
files, priority is given in the same order as the list in the previous example. That is, values defined in a file in the build type source set override the values defined in the same file in a product flavor, and so on. - Resources in the
res/
andasset/
directories are packaged together. If there are resources with the same name defined in two or more source sets, priority is given in the same order as the list in the previous example. - Gradle gives resources and manifests included with library module dependencies the lowest priority when building the app.
নির্ভরতা ঘোষণা করুন
To configure a dependency for a specific build variant or testing source set , prefix the name of the build variant or testing source set before the Implementation
keyword, as shown in the following example:
কোটলিন
dependencies { // Adds the local "mylibrary" module as a dependency to the "free" flavor. "freeImplementation"(project(":mylibrary")) // Adds a remote binary dependency only for local tests. testImplementation("junit:junit:4.12") // Adds a remote binary dependency only for the instrumented test APK. androidTestImplementation("com.android.support.test.espresso:espresso-core:3.6.1") }
গ্রোভি
dependencies { // Adds the local "mylibrary" module as a dependency to the "free" flavor. freeImplementation project(":mylibrary") // Adds a remote binary dependency only for local tests. testImplementation 'junit:junit:4.12' // Adds a remote binary dependency only for the instrumented test APK. androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.6.1' }
For more information about configuring dependencies, see Add build dependencies .
Use variant-aware dependency management
The Android Gradle plugin 3.0.0 and higher includes a new dependency mechanism that automatically matches variants when consuming a library. This means an app's debug
variant automatically consumes a library's debug
variant, and so on. It also works when using flavors: an app's freeDebug
variant will consume a library's freeDebug
variant.
For the plugin to accurately match variants, you need to provide matching fallbacks as described in the following section, for instances where a direct match is not possible.
For example, suppose your app configures a build type called "staging", but one of its library dependencies doesn't. When the plugin tries to build the "staging" version of your app, it won't know which version of the library to use, and you'll see an error message similar to the following:
Error:Failed to resolve: Could not resolve project :mylibrary. Required by: project :app
Resolve build errors related to variant matching
The plugin includes DSL elements to help you control how Gradle resolves situations in which a direct variant match between an app and a dependency is not possible.
The following is a list of issues related to variant-aware dependency matching and how to solve them using DSL properties:Your app includes a build type that a library dependency does not.
For example, your app includes a "staging" build type, but a dependency includes only "debug" and "release" build types.
Note that there is no issue when a library dependency includes a build type that your app doesn't. That's because the plugin never requests that build type from the dependency.
Use
matchingFallbacks
to specify alternative matches for a given build type, as shown here:কোটলিন
// In the app's build.gradle.kts file. android { buildTypes { getByName("debug") {} getByName("release") {} create("staging") { // Specifies a sorted list of fallback build types that the // plugin can try to use when a dependency does not include a // "staging" build type. You may specify as many fallbacks as you // like, and the plugin selects the first build type that's // available in the dependency. matchingFallbacks += listOf("debug", "qa", "release") } } }
গ্রোভি
// In the app's build.gradle file. android { buildTypes { debug {} release {} staging { // Specifies a sorted list of fallback build types that the // plugin can try to use when a dependency does not include a // "staging" build type. You may specify as many fallbacks as you // like, and the plugin selects the first build type that's // available in the dependency. matchingFallbacks = ['debug', 'qa', 'release'] } } }
For a given flavor dimension that exists in both the app and its library dependency, your app includes flavors that the library does not.
For example, both your app and its library dependencies include a "tier" flavor dimension. However, the "tier" dimension in the app includes "free" and "paid" flavors, but a dependency includes only "demo" and "paid" flavors for the same dimension.
Note that for a given flavor dimension that exists in both the app and its library dependencies, there is no issue when a library includes a product flavor that your app does not. That's because the plugin never requests that flavor from the dependency.
Use
matchingFallbacks
to specify alternative matches for the app's "free" product flavor, as shown here:কোটলিন
// In the app's build.gradle.kts file. android { defaultConfig{ // Don't configure matchingFallbacks in the defaultConfig block. // Instead, specify fallbacks for a given product flavor in the // productFlavors block, as shown below. } flavorDimensions += "tier" productFlavors { create("paid") { dimension = "tier" // Because the dependency already includes a "paid" flavor in its // "tier" dimension, you don't need to provide a list of fallbacks // for the "paid" flavor. } create("free") { dimension = "tier" // Specifies a sorted list of fallback flavors that the plugin // can try to use when a dependency's matching dimension does // not include a "free" flavor. Specify as many // fallbacks as you like; the plugin selects the first flavor // that's available in the dependency's "tier" dimension. matchingFallbacks += listOf("demo", "trial") } } }
গ্রোভি
// In the app's build.gradle file. android { defaultConfig{ // Don't configure matchingFallbacks in the defaultConfig block. // Instead, specify fallbacks for a given product flavor in the // productFlavors block, as shown below. } flavorDimensions 'tier' productFlavors { paid { dimension 'tier' // Because the dependency already includes a "paid" flavor in its // "tier" dimension, you don't need to provide a list of fallbacks // for the "paid" flavor. } free { dimension 'tier' // Specifies a sorted list of fallback flavors that the plugin // can try to use when a dependency's matching dimension does // not include a "free" flavor. Specify as many // fallbacks as you like; the plugin selects the first flavor // that's available in the dependency's "tier" dimension. matchingFallbacks = ['demo', 'trial'] } } }
A library dependency includes a flavor dimension that your app does not.
For example, a library dependency includes flavors for a "minApi" dimension, but your app includes flavors for only the "tier" dimension. When you want to build the "freeDebug" version of your app, the plugin doesn't know whether to use the "minApi23Debug" or "minApi18Debug" version of the dependency.
Note that there is no issue when your app includes a flavor dimension that a library dependency doesn't. That's because the plugin matches flavors of only the dimensions that exist in the dependency. For example, if a dependency does not include a dimension for ABIs, the "freeX86Debug" version of your app would use the "freeDebug" version of the dependency.
Use
missingDimensionStrategy
in thedefaultConfig
block to specify the default flavor for the plugin to select from each missing dimension, as shown in the following sample. You can also override your selections in theproductFlavors
block, so each flavor can specify a different matching strategy for a missing dimension.কোটলিন
// In the app's build.gradle.kts file. android { defaultConfig{ // Specifies a sorted list of flavors that the plugin can try to use from // a given dimension. This tells the plugin to select the "minApi18" flavor // when encountering a dependency that includes a "minApi" dimension. // You can include additional flavor names to provide a // sorted list of fallbacks for the dimension. missingDimensionStrategy("minApi", "minApi18", "minApi23") // Specify a missingDimensionStrategy property for each // dimension that exists in a local dependency but not in your app. missingDimensionStrategy("abi", "x86", "arm64") } flavorDimensions += "tier" productFlavors { create("free") { dimension = "tier" // You can override the default selection at the product flavor // level by configuring another missingDimensionStrategy property // for the "minApi" dimension. missingDimensionStrategy("minApi", "minApi23", "minApi18") } create("paid") {} } }
গ্রোভি
// In the app's build.gradle file. android { defaultConfig{ // Specifies a sorted list of flavors that the plugin can try to use from // a given dimension. This tells the plugin to select the "minApi18" flavor // when encountering a dependency that includes a "minApi" dimension. // You can include additional flavor names to provide a // sorted list of fallbacks for the dimension. missingDimensionStrategy 'minApi', 'minApi18', 'minApi23' // Specify a missingDimensionStrategy property for each // dimension that exists in a local dependency but not in your app. missingDimensionStrategy 'abi', 'x86', 'arm64' } flavorDimensions 'tier' productFlavors { free { dimension 'tier' // You can override the default selection at the product flavor // level by configuring another missingDimensionStrategy property // for the 'minApi' dimension. missingDimensionStrategy 'minApi', 'minApi23', 'minApi18' } paid {} } }
For more information, see matchingFallbacks
and missingDimensionStrategy
in the Android Gradle plugin DSL reference.
Configure signing settings
Gradle doesn't sign your release build's APK or AAB unless you explicitly define a signing configuration for this build. If you don't have a signing key yet, generate an upload key and keystore using Android Studio.
To manually configure the signing configurations for your release build type using Gradle build configurations:
- Create a keystore. A keystore is a binary file that contains a set of private keys. You must keep your keystore in a safe and secure place.
- একটি ব্যক্তিগত কী তৈরি করুন। A private key is used to sign your app for distribution and is never included with the app or disclosed to unauthorized third parties.
Add the signing configuration to the module-level
build.gradle.kts
file:কোটলিন
... android { ... defaultConfig {...} signingConfigs { create("release") { storeFile = file("myreleasekey.keystore") storePassword = "password" keyAlias = "MyReleaseKey" keyPassword = "password" } } buildTypes { getByName("release") { ... signingConfig = signingConfigs.getByName("release") } } }
গ্রোভি
... android { ... defaultConfig {...} signingConfigs { release { storeFile file("myreleasekey.keystore") storePassword "password" keyAlias "MyReleaseKey" keyPassword "password" } } buildTypes { release { ... signingConfig signingConfigs.release } } }
Note: Including the passwords for your release key and keystore inside the build file is not a good security practice. Instead, configure the build file to obtain these passwords from environment variables or have the build process prompt you for these passwords.
To obtain these passwords from environment variables:
কোটলিন
storePassword = System.getenv("KSTOREPWD") keyPassword = System.getenv("KEYPWD")
গ্রোভি
storePassword System.getenv("KSTOREPWD") keyPassword System.getenv("KEYPWD")
Alternatively, you can load the keystore from a local properties file. For security reasons, don't add this file to source control. Instead, set it up locally for each developer. To learn more, read Remove signing information from your build files .
After you complete this process, you can distribute your app and publish it on Google Play.
সতর্কতা: আপনার কীস্টোর এবং প্রাইভেট কী একটি নিরাপদ এবং সুরক্ষিত জায়গায় রাখুন এবং নিশ্চিত করুন যে আপনার কাছে সেগুলির নিরাপদ ব্যাকআপ আছে। If you use Play App Signing and you lose your upload key, you can request a reset using the Play Console. If you are publishing an app without Play App Signing (for apps created before August 2021) and you lose your app signing key, you will not be able to publish any updates to your app, since you must always sign all versions of your app with the same key.
Signing Wear OS apps
When publishing Wear OS apps, both the watch APK and optional phone APK must be signed with the same key. For more information on packaging and signing Wear OS apps, see Package and distribute Wear apps .
,This page shows you how you can configure build variants to create different versions of your app from a single project and how to properly manage your dependencies and signing configurations.
Each build variant represents a different version of your app that you can build. For example, you might want to build one version of your app that's free with a limited set of content, and another paid version that includes more. You can also build different versions of your app that target different devices, based on API level or other device variations.
Build variants are the result of Gradle using a specific set of rules to combine settings, code, and resources configured in your build types and product flavors. Although you don't configure build variants directly, you do configure the build types and product flavors that form them.
For example, a "demo" product flavor might specify certain features and device requirements, such as custom source code, resources, and minimum API levels, while the "debug" build type applies different build and packaging settings, such as debug options and signing keys. The build variant that combines these two is the "demoDebug" version of your app, and it includes a combination of the configurations and resources included in the "demo" product flavor, "debug" build type, and main/
source set.
বিল্ড প্রকারগুলি কনফিগার করুন
You can create and configure build types inside the android
block of the module-level build.gradle.kts
file. When you create a new module, Android Studio automatically creates the debug and release build types. Although the debug build type doesn't appear in the build configuration file, Android Studio configures it with debuggable true
. This lets you debug the app on secure Android devices and configures app signing with a generic debug keystore.
You can add the debug build type to your configuration if you want to add or change certain settings. The following sample specifies an applicationIdSuffix
for the debug build type and configures a "staging" build type that is initialized using settings from the debug build type:
কোটলিন
android { defaultConfig { manifestPlaceholders["hostName"] = "www.example.com" ... } buildTypes { getByName("release") { isMinifyEnabled = true proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro") } getByName("debug") { applicationIdSuffix = ".debug" isDebuggable = true } /** * The `initWith` property lets you copy configurations from other build types, * then configure only the settings you want to change. This one copies the debug build * type, and then changes the manifest placeholder and application ID. */ create("staging") { initWith(getByName("debug")) manifestPlaceholders["hostName"] = "internal.example.com" applicationIdSuffix = ".debugStaging" } } }
গ্রোভি
android { defaultConfig { manifestPlaceholders = [hostName:"www.example.com"] ... } buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } debug { applicationIdSuffix ".debug" debuggable true } /** * The `initWith` property lets you copy configurations from other build types, * then configure only the settings you want to change. This one copies the debug build * type, and then changes the manifest placeholder and application ID. */ staging { initWith debug manifestPlaceholders = [hostName:"internal.example.com"] applicationIdSuffix ".debugStaging" } } }
Note: When you make changes to a build configuration file, Android Studio requires that you sync your project with the new configuration. To sync your project, click Sync Now in the notification bar that appears when you make a change or click Sync Project টুলবার থেকে। If Android Studio notices any errors with your configuration, the Messages window appears to describe the issue.
To learn more about all the properties you can configure with build types, read the BuildType
reference.
Configure product flavors
পণ্যের স্বাদ তৈরি করা বিল্ড প্রকার তৈরির অনুরূপ। আপনার বিল্ড কনফিগারেশনে প্রোডাক্ট productFlavors
ব্লকে পণ্যের স্বাদ যোগ করুন এবং আপনি যে সেটিংস চান তা অন্তর্ভুক্ত করুন। The product flavors support the same properties as defaultConfig
, because defaultConfig
actually belongs to the ProductFlavor
class. This means you can provide the base configuration for all flavors in the defaultConfig
block, and each flavor can change any of these default values, such as the applicationId
. To learn more about the application ID, read Set the application ID .
Note: You still need to specify a package name using the package
attribute in the main/
manifest file. You must also use that package name in your source code to refer to the R
class or to resolve any relative activity or service registration. This lets you use applicationId
to give each product flavor a unique ID for packaging and distribution without having to change your source code.
All flavors must belong to a named flavor dimension, which is a group of product flavors. You must assign all flavors to a flavor dimension; otherwise, you will get the following build error.
Error: All flavors must now belong to a named flavor dimension. The flavor 'flavor_name' is not assigned to a flavor dimension.
If a given module specifies only one flavor dimension, the Android Gradle plugin automatically assigns all of the module's flavors to that dimension.
The following code sample creates a flavor dimension named "version" and adds "demo" and "full" product flavors. These flavors provide their own applicationIdSuffix
and versionNameSuffix
:
কোটলিন
android { ... defaultConfig {...} buildTypes { getByName("debug"){...} getByName("release"){...} } // Specifies one flavor dimension. flavorDimensions += "version" productFlavors { create("demo") { // Assigns this product flavor to the "version" flavor dimension. // If you are using only one dimension, this property is optional, // and the plugin automatically assigns all the module's flavors to // that dimension. dimension = "version" applicationIdSuffix = ".demo" versionNameSuffix = "-demo" } create("full") { dimension = "version" applicationIdSuffix = ".full" versionNameSuffix = "-full" } } }
গ্রোভি
android { ... defaultConfig {...} buildTypes { debug{...} release{...} } // Specifies one flavor dimension. flavorDimensions "version" productFlavors { demo { // Assigns this product flavor to the "version" flavor dimension. // If you are using only one dimension, this property is optional, // and the plugin automatically assigns all the module's flavors to // that dimension. dimension "version" applicationIdSuffix ".demo" versionNameSuffix "-demo" } full { dimension "version" applicationIdSuffix ".full" versionNameSuffix "-full" } } }
Note: If you have a legacy app (created before August 2021) that you distribute using APKs on Google Play, to distribute your app using multiple APK support in Google Play, assign the same applicationId
value to all variants and give each variant a different versionCode
. To distribute different variants of your app as separate apps in Google Play, you need to assign a different applicationId
to each variant.
After you create and configure your product flavors, click Sync Now in the notification bar. Once the sync completes, Gradle automatically creates build variants based on your build types and product flavors and names them according to <product-flavor><Build-Type>
. For example, if you created "demo" and "full" product flavors, and kept the default "debug" and "release" build types, Gradle creates the following build variants:
-
demoDebug
-
demoRelease
-
fullDebug
-
fullRelease
To select which build variant to build and run, go to Build > Select Build Variant and select a build variant from the menu. To start customizing each build variant with its own features and resources, you'll need to create and manage source sets , as described on this page.
Change the application ID for build variants
When you build an APK or AAB for your app, the build tools tag the app with the application ID defined in the defaultConfig
block from the build.gradle.kts
file, as shown in the following example. However, if you want to create different versions of your app to appear as separate listings on Google Play Store, such as a "free" and "pro" version, you need to create separate build variants that each have a different application ID.
In this case, define each build variant as a separate product flavor . For each flavor inside the productFlavors
block, you can redefine the applicationId
property, or you can instead append a segment to the default application ID using applicationIdSuffix
, as shown here:
কোটলিন
android { defaultConfig { applicationId = "com.example.myapp" } productFlavors { create("free") { applicationIdSuffix = ".free" } create("pro") { applicationIdSuffix = ".pro" } } }
গ্রোভি
android { defaultConfig { applicationId "com.example.myapp" } productFlavors { free { applicationIdSuffix ".free" } pro { applicationIdSuffix ".pro" } } }
This way, the application ID for the "free" product flavor is "com.example.myapp.free".
You can also use applicationIdSuffix
to append a segment based on your build type , as shown here:
কোটলিন
android { ... buildTypes { getByName("debug") { applicationIdSuffix = ".debug" } } }
গ্রোভি
android { ... buildTypes { debug { applicationIdSuffix ".debug" } } }
Because Gradle applies the build type configuration after the product flavor, the application ID for the "free debug" build variant is "com.example.myapp.free.debug". This is useful when you want to have both the debug and the release build on the same device, because no two apps can have the same application ID.
If you have a legacy app (created before August 2021) that you distribute using APKs on Google Play, and you want to use the same app listing to distribute multiple APKs that each target a different device configuration, such as the API level, then you must use the same application ID for each build variant but give each APK a differentversionCode
. For more information, read about Multiple APK support . Publishing using AABs is unaffected, as it uses a single artifact that uses a single version code and application ID by default. Tip: If you need to reference the application ID in your manifest file, you can use the ${applicationId}
placeholder in any manifest attribute. During a build, Gradle replaces this tag with the actual application ID. For more information, see Inject build variables into the manifest .
গন্ধ মাত্রা সঙ্গে একাধিক পণ্য স্বাদ একত্রিত
In some cases, you may want to combine configurations from multiple product flavors. For example, you may want to create different configurations for the "full" and "demo" product flavors that are based on API level. To do this, the Android Gradle plugin lets you create multiple groups of product flavors as flavor dimensions.
আপনার অ্যাপ তৈরি করার সময়, গ্রেডল চূড়ান্ত বিল্ড বৈকল্পিক তৈরি করতে বিল্ড টাইপ কনফিগারেশনের সাথে আপনার সংজ্ঞায়িত প্রতিটি ফ্লেভার ডাইমেনশন থেকে একটি প্রোডাক্ট ফ্লেভার কনফিগারেশন একত্রিত করে। Gradle doesn't combine product flavors that belong to the same flavor dimension.
The following code sample uses the flavorDimensions
property to create a "mode" flavor dimension to group the "full" and "demo" product flavors and an "api" flavor dimension to group product flavor configurations based on API level:
কোটলিন
android { ... buildTypes { getByName("debug") {...} getByName("release") {...} } // Specifies the flavor dimensions you want to use. The order in which you // list the dimensions determines their priority, from highest to lowest, // when Gradle merges variant sources and configurations. You must assign // each product flavor you configure to one of the flavor dimensions. flavorDimensions += listOf("api", "mode") productFlavors { create("demo") { // Assigns this product flavor to the "mode" flavor dimension. dimension = "mode" ... } create("full") { dimension = "mode" ... } // Configurations in the "api" product flavors override those in "mode" // flavors and the defaultConfig block. Gradle determines the priority // between flavor dimensions based on the order in which they appear next // to the flavorDimensions property, with the first dimension having a higher // priority than the second, and so on. create("minApi24") { dimension = "api" minSdk = 24 // To ensure the target device receives the version of the app with // the highest compatible API level, assign version codes in increasing // value with API level. versionCode = 30000 + (android.defaultConfig.versionCode ?: 0) versionNameSuffix = "-minApi24" ... } create("minApi23") { dimension = "api" minSdk = 23 versionCode = 20000 + (android.defaultConfig.versionCode ?: 0) versionNameSuffix = "-minApi23" ... } create("minApi21") { dimension = "api" minSdk = 21 versionCode = 10000 + (android.defaultConfig.versionCode ?: 0) versionNameSuffix = "-minApi21" ... } } } ...
গ্রোভি
android { ... buildTypes { debug {...} release {...} } // Specifies the flavor dimensions you want to use. The order in which you // list the dimensions determines their priority, from highest to lowest, // when Gradle merges variant sources and configurations. You must assign // each product flavor you configure to one of the flavor dimensions. flavorDimensions "api", "mode" productFlavors { demo { // Assigns this product flavor to the "mode" flavor dimension. dimension "mode" ... } full { dimension "mode" ... } // Configurations in the "api" product flavors override those in "mode" // flavors and the defaultConfig block. Gradle determines the priority // between flavor dimensions based on the order in which they appear next // to the flavorDimensions property, with the first dimension having a higher // priority than the second, and so on. minApi24 { dimension "api" minSdkVersion 24 // To ensure the target device receives the version of the app with // the highest compatible API level, assign version codes in increasing // value with API level. versionCode 30000 + android.defaultConfig.versionCode versionNameSuffix "-minApi24" ... } minApi23 { dimension "api" minSdkVersion 23 versionCode 20000 + android.defaultConfig.versionCode versionNameSuffix "-minApi23" ... } minApi21 { dimension "api" minSdkVersion 21 versionCode 10000 + android.defaultConfig.versionCode versionNameSuffix "-minApi21" ... } } } ...
The number of build variants Gradle creates is equal to the product of the number of flavors in each flavor dimension and the number of build types you configure. When Gradle names each build variant or corresponding artifacts, product flavors belonging to higher-priority flavor dimension appear first, followed by those from lower-priority dimensions, followed by the build type.
Using the previous build configuration as an example, Gradle creates a total of 12 build variants with the following naming scheme:
- Build variant:
[minApi24, minApi23, minApi21][Demo, Full][Debug, Release]
- Corresponding APK:
app-[minApi24, minApi23, minApi21]-[demo, full]-[debug, release].apk
- যেমন,
- Build variant:
minApi24DemoDebug
- Corresponding APK:
app-minApi24-demo-debug.apk
In addition to the source set directories you can create for each individual product flavor and build variant, you can also create source set directories for each combination of product flavors. For example, you can create and add Java sources to the src/demoMinApi24/java/
directory, and Gradle uses those sources only when building a variant that combines those two product flavors.
Source sets you create for product flavor combinations have a higher priority than source sets that belong to each individual product flavor. To learn more about source sets and how Gradle merges resources, read the section about how to create source sets .
ফিল্টার বৈকল্পিক
Gradle আপনার কনফিগার করা পণ্যের স্বাদ এবং বিল্ড প্রকারের প্রতিটি সম্ভাব্য সমন্বয়ের জন্য একটি বিল্ড বৈকল্পিক তৈরি করে। However, there may be certain build variants that you don't need or that don't make sense in the context of your project. To remove certain build variant configurations, create a variant filter in your module-level build.gradle.kts
file.
Using the build configuration from the previous section as an example, suppose you plan to support only API levels 23 and higher for the demo version of the app. You can use the variantFilter
block to filter out all build variant configurations that combine the "minApi21" and "demo" product flavors:
কোটলিন
android { ... buildTypes {...} flavorDimensions += listOf("api", "mode") productFlavors { create("demo") {...} create("full") {...} create("minApi24") {...} create("minApi23") {...} create("minApi21") {...} } } androidComponents { beforeVariants { variantBuilder -> // To check for a certain build type, use variantBuilder.buildType == "<buildType>" if (variantBuilder.productFlavors.containsAll(listOf("api" to "minApi21", "mode" to "demo"))) { // Gradle ignores any variants that satisfy the conditions above. variantBuilder.enable = false } } } ...
গ্রোভি
android { ... buildTypes {...} flavorDimensions "api", "mode" productFlavors { demo {...} full {...} minApi24 {...} minApi23 {...} minApi21 {...} } variantFilter { variant -> def names = variant.flavors*.name // To check for a certain build type, use variant.buildType.name == "<buildType>" if (names.contains("minApi21") && names.contains("demo")) { // Gradle ignores any variants that satisfy the conditions above. setIgnore(true) } } } ...
Once you add a variant filter to your build configuration and click Sync Now in the notification bar, Gradle ignores any build variants that meet the conditions you specify. The build variants no longer appear in the menu when you click Build > Select Build Variant from the menu bar or Build Variants in the tool window bar.
সোর্স সেট তৈরি করুন
ডিফল্টরূপে, অ্যান্ড্রয়েড স্টুডিও আপনার সমস্ত বিল্ড ভেরিয়েন্টের মধ্যে শেয়ার করতে চান এমন সবকিছুর জন্য main/
উৎস সেট এবং ডিরেক্টরি তৈরি করে। However, you can create new source sets to control exactly which files Gradle compiles and packages for specific build types, product flavors, combinations of product flavors (when using flavor dimensions ), and build variants.
উদাহরণস্বরূপ, আপনি main/
উৎস সেটে মৌলিক কার্যকারিতা নির্ধারণ করতে পারেন এবং বিভিন্ন ক্লায়েন্টের জন্য আপনার অ্যাপের ব্র্যান্ডিং পরিবর্তন করতে পণ্যের স্বাদের উৎস সেট ব্যবহার করতে পারেন, অথবা শুধুমাত্র ডিবাগ বিল্ড টাইপ ব্যবহার করে এমন বিল্ড ভেরিয়েন্টের জন্য বিশেষ অনুমতি এবং লগিং কার্যকারিতা অন্তর্ভুক্ত করতে পারেন।
Gradle expects source set files and directories to be organized in a certain way, similar to the main/
source set. For example, Gradle expects Kotlin or Java class files that are specific to your "debug" build type to be located in the src/debug/kotlin/
or src/debug/java/
directories.
The Android Gradle plugin provides a useful Gradle task that shows you how to organize your files for each of your build types, product flavors, and build variants. For example, the following sample from the task output describes where Gradle expects to find certain files for the "debug" build type:
------------------------------------------------------------ Project :app ------------------------------------------------------------ ... debug ---- Compile configuration: debugCompile build.gradle name: android.sourceSets.debug Java sources: [app/src/debug/java] Kotlin sources: [app/src/debug/kotlin, app/src/debug/java] Manifest file: app/src/debug/AndroidManifest.xml Android resources: [app/src/debug/res] Assets: [app/src/debug/assets] AIDL sources: [app/src/debug/aidl] RenderScript sources: [app/src/debug/rs] JNI sources: [app/src/debug/jni] JNI libraries: [app/src/debug/jniLibs] Java-style resources: [app/src/debug/resources]
To view this output, proceed as follows:
- Click Gradle in the tool window bar.
Navigate to MyApplication > Tasks > android and double-click sourceSets .
To see the Tasks folder, you must let Gradle build the task list during sync. এটি করতে, এই পদক্ষেপগুলি অনুসরণ করুন:
- Click File > Settings > Experimental ( Android Studio > Settings > Experimental on macOS).
- Deselect Do not build Gradle task list during Gradle sync .
- After Gradle executes the task, the Run window opens to display the output.
Note: The task output also shows you how to organize source sets for files you want to use to run tests for your app, such as the test/
and androidTest/
testing source sets .
আপনি যখন একটি নতুন বিল্ড ভেরিয়েন্ট তৈরি করেন, তখন অ্যান্ড্রয়েড স্টুডিও আপনার জন্য সোর্স সেট ডিরেক্টরি তৈরি করে না, তবে এটি আপনাকে সাহায্য করার জন্য কয়েকটি বিকল্প দেয়। উদাহরণস্বরূপ, আপনার "ডিবাগ" বিল্ড টাইপের জন্য java/
ডিরেক্টরি তৈরি করতে:
- Open the Project pane and select the Project view from the menu at the top of the pane.
- Navigate to
MyProject/app/src/
. - Right-click the
src
directory and select New > Directory . - From the menu under Gradle Source Sets , select full/java .
- এন্টার টিপুন।
Android Studio creates a source set directory for your debug build type and then creates the java/
directory inside it. Alternatively, Android Studio can create the directories for you when you add a new file to your project for a specific build variant.
For example, to create a values XML file for your "debug" build type:
- In the Project pane, right-click the
src
directory and select New > XML > Values XML File . - Enter the name for the XML file or keep the default name.
- From the menu next to Target Source Set , select debug .
- শেষ ক্লিক করুন.
Because the "debug" build type was specified as the target source set, Android Studio automatically creates the necessary directories when it creates the XML file. The resulting directory structure looks like figure 1.

Figure 1. New source set directories for the "debug" build type.
Active source sets have a green indicator in their icon to show that they are active. The debug
source set is suffixed with [main]
to show that it will be merged in to the main
source set.
Using the same procedure, you can also create source set directories for product flavors, such as src/demo/
, and build variants, such as src/demoDebug/
. Additionally, you can create testing source sets that target specific build variants, such as src/androidTestDemoDebug/
. To learn more, read about testing source sets .
Change default source set configurations
If you have sources that are not organized into the default source set file structure that Gradle expects, as described in the previous section about creating source sets , you can use the sourceSets
block to change where Gradle looks to gather files for each component of a source set.
The sourceSets
block must be in the android
block. You don't need to relocate the source files; you only need to provide Gradle with the path(s), relative to the module-level build.gradle.kts
file, where Gradle can find files for each source set component. To learn which components you can configure and whether you can map them to multiple files or directories, see the Android Gradle plugin API reference .
The following code sample maps sources from the app/other/
directory to certain components of the main
source set and changes the root directory of the androidTest
source set:
কোটলিন
android { ... // Encapsulates configurations for the main source set. sourceSets.getByName("main") { // Changes the directory for Java sources. The default directory is // 'src/main/java'. java.setSrcDirs(listOf("other/java")) // If you list multiple directories, Gradle uses all of them to collect // sources. Because Gradle gives these directories equal priority, if // you define the same resource in more than one directory, you receive an // error when merging resources. The default directory is 'src/main/res'. res.setSrcDirs(listOf("other/res1", "other/res2")) // Note: Avoid specifying a directory that is a parent to one // or more other directories you specify. For example, avoid the following: // res.srcDirs = ['other/res1', 'other/res1/layouts', 'other/res1/strings'] // Specify either only the root 'other/res1' directory or only the // nested 'other/res1/layouts' and 'other/res1/strings' directories. // For each source set, you can specify only one Android manifest. // By default, Android Studio creates a manifest for your main source // set in the src/main/ directory. manifest.srcFile("other/AndroidManifest.xml") ... } // Create additional blocks to configure other source sets. sourceSets.getByName("androidTest") { // If all the files for a source set are located under a single root // directory, you can specify that directory using the setRoot property. // When gathering sources for the source set, Gradle looks only in locations // relative to the root directory you specify. For example, after applying the // configuration below for the androidTest source set, Gradle looks for Java // sources only in the src/tests/java/ directory. setRoot("src/tests") ... } } ...
গ্রোভি
android { ... sourceSets { // Encapsulates configurations for the main source set. main { // Changes the directory for Java sources. The default directory is // 'src/main/java'. java.srcDirs = ['other/java'] // If you list multiple directories, Gradle uses all of them to collect // sources. Because Gradle gives these directories equal priority, if // you define the same resource in more than one directory, you receive an // error when merging resources. The default directory is 'src/main/res'. res.srcDirs = ['other/res1', 'other/res2'] // Note: Avoid specifying a directory that is a parent to one // or more other directories you specify. For example, avoid the following: // res.srcDirs = ['other/res1', 'other/res1/layouts', 'other/res1/strings'] // Specify either only the root 'other/res1' directory or only the // nested 'other/res1/layouts' and 'other/res1/strings' directories. // For each source set, you can specify only one Android manifest. // By default, Android Studio creates a manifest for your main source // set in the src/main/ directory. manifest.srcFile 'other/AndroidManifest.xml' ... } // Create additional blocks to configure other source sets. androidTest { // If all the files for a source set are located under a single root // directory, you can specify that directory using the setRoot property. // When gathering sources for the source set, Gradle looks only in locations // relative to the root directory you specify. For example, after applying the // configuration below for the androidTest source set, Gradle looks for Java // sources only in the src/tests/java/ directory. setRoot 'src/tests' ... } } } ...
Note that a source directory can only belong to one source set. For example, you can't share the same test sources with both the test
and androidTest
source sets. This is because Android Studio creates separate IntelliJ modules for each source set and can't support duplicate content roots across source sets.
Build with source sets
You can use source set directories to contain the code and resources you want packaged only with certain configurations. For example, if you are building the "demoDebug" build variant, which is the crossproduct of a "demo" product flavor and "debug" build type, Gradle looks at these directories and gives them the following priority:
-
src/demoDebug/
(build variant source set) -
src/debug/
(build type source set) -
src/demo/
(product flavor source set) -
src/main/
(main source set)
Source sets created for combinations of product flavors must include all flavor dimensions. For example, the build variant source set must be the combination of the build type and all flavor dimensions. Merging code and resources involving folders that cover multiple but not all flavor dimensions is not supported.
If you combine multiple product flavors , priority between the product flavors is determined by the flavor dimension they belong to. When listing flavor dimensions with the android.flavorDimensions
property, product flavors that belong to the first flavor dimension you list have a higher priority than those belonging to the second flavor dimension, and so on. Additionally, source sets you create for combinations of product flavors have a higher priority than source sets that belong to an individual product flavor.
The priority order determines which source set has a higher priority when Gradle combines code and resources. Because the demoDebug/
source set directory likely contains files that are specific to that build variant, if demoDebug/
includes a file that is also defined in debug/
, Gradle uses the file in the demoDebug/
source set. Similarly, Gradle gives files in the build type and product flavor source sets a higher priority than the same files in main/
. Gradle considers this priority order when applying the following build rules:
- All source code in the
kotlin/
orjava/
directories are compiled together to generate a single output.Note: For a given build variant, Gradle throws a build error if it encounters two or more source set directories that have defined the same Kotlin or Java class. For example, when building a debug app, you can't define both
src/debug/Utility.kt
andsrc/main/Utility.kt
, because Gradle looks at both these directories during the build process and throws a "duplicate class" error. If you want different versions ofUtility.kt
for different build types, each build type must define its own version of the file and not include it in themain/
source set. - Manifests are merged together into a single manifest. Priority is given in the same order as the list in the previous example. That is, manifest settings for a build type override the manifest settings for a product flavor, and so on. To learn more, read about manifest merging .
- Files in the
values/
directories are merged together. If two files have the same name, such as twostrings.xml
files, priority is given in the same order as the list in the previous example. That is, values defined in a file in the build type source set override the values defined in the same file in a product flavor, and so on. - Resources in the
res/
andasset/
directories are packaged together. If there are resources with the same name defined in two or more source sets, priority is given in the same order as the list in the previous example. - Gradle gives resources and manifests included with library module dependencies the lowest priority when building the app.
নির্ভরতা ঘোষণা করুন
To configure a dependency for a specific build variant or testing source set , prefix the name of the build variant or testing source set before the Implementation
keyword, as shown in the following example:
কোটলিন
dependencies { // Adds the local "mylibrary" module as a dependency to the "free" flavor. "freeImplementation"(project(":mylibrary")) // Adds a remote binary dependency only for local tests. testImplementation("junit:junit:4.12") // Adds a remote binary dependency only for the instrumented test APK. androidTestImplementation("com.android.support.test.espresso:espresso-core:3.6.1") }
গ্রোভি
dependencies { // Adds the local "mylibrary" module as a dependency to the "free" flavor. freeImplementation project(":mylibrary") // Adds a remote binary dependency only for local tests. testImplementation 'junit:junit:4.12' // Adds a remote binary dependency only for the instrumented test APK. androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.6.1' }
For more information about configuring dependencies, see Add build dependencies .
Use variant-aware dependency management
The Android Gradle plugin 3.0.0 and higher includes a new dependency mechanism that automatically matches variants when consuming a library. This means an app's debug
variant automatically consumes a library's debug
variant, and so on. It also works when using flavors: an app's freeDebug
variant will consume a library's freeDebug
variant.
For the plugin to accurately match variants, you need to provide matching fallbacks as described in the following section, for instances where a direct match is not possible.
For example, suppose your app configures a build type called "staging", but one of its library dependencies doesn't. When the plugin tries to build the "staging" version of your app, it won't know which version of the library to use, and you'll see an error message similar to the following:
Error:Failed to resolve: Could not resolve project :mylibrary. Required by: project :app
Resolve build errors related to variant matching
The plugin includes DSL elements to help you control how Gradle resolves situations in which a direct variant match between an app and a dependency is not possible.
The following is a list of issues related to variant-aware dependency matching and how to solve them using DSL properties:Your app includes a build type that a library dependency does not.
For example, your app includes a "staging" build type, but a dependency includes only "debug" and "release" build types.
Note that there is no issue when a library dependency includes a build type that your app doesn't. That's because the plugin never requests that build type from the dependency.
Use
matchingFallbacks
to specify alternative matches for a given build type, as shown here:কোটলিন
// In the app's build.gradle.kts file. android { buildTypes { getByName("debug") {} getByName("release") {} create("staging") { // Specifies a sorted list of fallback build types that the // plugin can try to use when a dependency does not include a // "staging" build type. You may specify as many fallbacks as you // like, and the plugin selects the first build type that's // available in the dependency. matchingFallbacks += listOf("debug", "qa", "release") } } }
গ্রোভি
// In the app's build.gradle file. android { buildTypes { debug {} release {} staging { // Specifies a sorted list of fallback build types that the // plugin can try to use when a dependency does not include a // "staging" build type. You may specify as many fallbacks as you // like, and the plugin selects the first build type that's // available in the dependency. matchingFallbacks = ['debug', 'qa', 'release'] } } }
For a given flavor dimension that exists in both the app and its library dependency, your app includes flavors that the library does not.
For example, both your app and its library dependencies include a "tier" flavor dimension. However, the "tier" dimension in the app includes "free" and "paid" flavors, but a dependency includes only "demo" and "paid" flavors for the same dimension.
Note that for a given flavor dimension that exists in both the app and its library dependencies, there is no issue when a library includes a product flavor that your app does not. That's because the plugin never requests that flavor from the dependency.
Use
matchingFallbacks
to specify alternative matches for the app's "free" product flavor, as shown here:কোটলিন
// In the app's build.gradle.kts file. android { defaultConfig{ // Don't configure matchingFallbacks in the defaultConfig block. // Instead, specify fallbacks for a given product flavor in the // productFlavors block, as shown below. } flavorDimensions += "tier" productFlavors { create("paid") { dimension = "tier" // Because the dependency already includes a "paid" flavor in its // "tier" dimension, you don't need to provide a list of fallbacks // for the "paid" flavor. } create("free") { dimension = "tier" // Specifies a sorted list of fallback flavors that the plugin // can try to use when a dependency's matching dimension does // not include a "free" flavor. Specify as many // fallbacks as you like; the plugin selects the first flavor // that's available in the dependency's "tier" dimension. matchingFallbacks += listOf("demo", "trial") } } }
গ্রোভি
// In the app's build.gradle file. android { defaultConfig{ // Don't configure matchingFallbacks in the defaultConfig block. // Instead, specify fallbacks for a given product flavor in the // productFlavors block, as shown below. } flavorDimensions 'tier' productFlavors { paid { dimension 'tier' // Because the dependency already includes a "paid" flavor in its // "tier" dimension, you don't need to provide a list of fallbacks // for the "paid" flavor. } free { dimension 'tier' // Specifies a sorted list of fallback flavors that the plugin // can try to use when a dependency's matching dimension does // not include a "free" flavor. Specify as many // fallbacks as you like; the plugin selects the first flavor // that's available in the dependency's "tier" dimension. matchingFallbacks = ['demo', 'trial'] } } }
A library dependency includes a flavor dimension that your app does not.
For example, a library dependency includes flavors for a "minApi" dimension, but your app includes flavors for only the "tier" dimension. When you want to build the "freeDebug" version of your app, the plugin doesn't know whether to use the "minApi23Debug" or "minApi18Debug" version of the dependency.
Note that there is no issue when your app includes a flavor dimension that a library dependency doesn't. That's because the plugin matches flavors of only the dimensions that exist in the dependency. For example, if a dependency does not include a dimension for ABIs, the "freeX86Debug" version of your app would use the "freeDebug" version of the dependency.
Use
missingDimensionStrategy
in thedefaultConfig
block to specify the default flavor for the plugin to select from each missing dimension, as shown in the following sample. You can also override your selections in theproductFlavors
block, so each flavor can specify a different matching strategy for a missing dimension.কোটলিন
// In the app's build.gradle.kts file. android { defaultConfig{ // Specifies a sorted list of flavors that the plugin can try to use from // a given dimension. This tells the plugin to select the "minApi18" flavor // when encountering a dependency that includes a "minApi" dimension. // You can include additional flavor names to provide a // sorted list of fallbacks for the dimension. missingDimensionStrategy("minApi", "minApi18", "minApi23") // Specify a missingDimensionStrategy property for each // dimension that exists in a local dependency but not in your app. missingDimensionStrategy("abi", "x86", "arm64") } flavorDimensions += "tier" productFlavors { create("free") { dimension = "tier" // You can override the default selection at the product flavor // level by configuring another missingDimensionStrategy property // for the "minApi" dimension. missingDimensionStrategy("minApi", "minApi23", "minApi18") } create("paid") {} } }
গ্রোভি
// In the app's build.gradle file. android { defaultConfig{ // Specifies a sorted list of flavors that the plugin can try to use from // a given dimension. This tells the plugin to select the "minApi18" flavor // when encountering a dependency that includes a "minApi" dimension. // You can include additional flavor names to provide a // sorted list of fallbacks for the dimension. missingDimensionStrategy 'minApi', 'minApi18', 'minApi23' // Specify a missingDimensionStrategy property for each // dimension that exists in a local dependency but not in your app. missingDimensionStrategy 'abi', 'x86', 'arm64' } flavorDimensions 'tier' productFlavors { free { dimension 'tier' // You can override the default selection at the product flavor // level by configuring another missingDimensionStrategy property // for the 'minApi' dimension. missingDimensionStrategy 'minApi', 'minApi23', 'minApi18' } paid {} } }
For more information, see matchingFallbacks
and missingDimensionStrategy
in the Android Gradle plugin DSL reference.
Configure signing settings
Gradle doesn't sign your release build's APK or AAB unless you explicitly define a signing configuration for this build. If you don't have a signing key yet, generate an upload key and keystore using Android Studio.
To manually configure the signing configurations for your release build type using Gradle build configurations:
- Create a keystore. A keystore is a binary file that contains a set of private keys. You must keep your keystore in a safe and secure place.
- একটি ব্যক্তিগত কী তৈরি করুন। A private key is used to sign your app for distribution and is never included with the app or disclosed to unauthorized third parties.
Add the signing configuration to the module-level
build.gradle.kts
file:কোটলিন
... android { ... defaultConfig {...} signingConfigs { create("release") { storeFile = file("myreleasekey.keystore") storePassword = "password" keyAlias = "MyReleaseKey" keyPassword = "password" } } buildTypes { getByName("release") { ... signingConfig = signingConfigs.getByName("release") } } }
গ্রোভি
... android { ... defaultConfig {...} signingConfigs { release { storeFile file("myreleasekey.keystore") storePassword "password" keyAlias "MyReleaseKey" keyPassword "password" } } buildTypes { release { ... signingConfig signingConfigs.release } } }
Note: Including the passwords for your release key and keystore inside the build file is not a good security practice. Instead, configure the build file to obtain these passwords from environment variables or have the build process prompt you for these passwords.
To obtain these passwords from environment variables:
কোটলিন
storePassword = System.getenv("KSTOREPWD") keyPassword = System.getenv("KEYPWD")
গ্রোভি
storePassword System.getenv("KSTOREPWD") keyPassword System.getenv("KEYPWD")
Alternatively, you can load the keystore from a local properties file. For security reasons, don't add this file to source control. Instead, set it up locally for each developer. To learn more, read Remove signing information from your build files .
After you complete this process, you can distribute your app and publish it on Google Play.
সতর্কতা: আপনার কীস্টোর এবং প্রাইভেট কী একটি নিরাপদ এবং সুরক্ষিত জায়গায় রাখুন এবং নিশ্চিত করুন যে আপনার কাছে সেগুলির নিরাপদ ব্যাকআপ আছে। If you use Play App Signing and you lose your upload key, you can request a reset using the Play Console. If you are publishing an app without Play App Signing (for apps created before August 2021) and you lose your app signing key, you will not be able to publish any updates to your app, since you must always sign all versions of your app with the same key.
Signing Wear OS apps
When publishing Wear OS apps, both the watch APK and optional phone APK must be signed with the same key. For more information on packaging and signing Wear OS apps, see Package and distribute Wear apps .