توضّح لك هذه الصفحة كيفية ضبط صيغ الإصدار من أجل إنشاء إصدارات مختلفة من التطبيق من مشروع واحد، وكيف لإدارة التبعيات وعمليات إعداد التوقيع بشكل صحيح.
تمثّل كل صيغة إصدار إصدارًا مختلفًا من تطبيقك التي يمكنك إنشاؤها. على سبيل المثال، قد ترغب في إنشاء إصدار واحد من تطبيقك مجانًا مع مجموعة محدودة من المحتوى ونسخة مدفوعة أخرى تتضمن المزيد. يمكنك أيضًا إنشاء إصدارات مختلفة من تطبيقك تستهدف الأجهزة المختلفة بناءً على مستوى واجهة برمجة التطبيقات أو الأشكال الأخرى للأجهزة
إن متغيرات التصميم هي نتيجة Gradle باستخدام دالة محددة مجموعة من القواعد لدمج الإعدادات والرموز والموارد التي تم ضبطها في وإنشاء أنواع ونكهات المنتج. على الرغم من عدم ضبط صيغ الإصدار مباشرةً، يمكنك إعداد أنواع التصميم ونكهات المنتج التي تشكلها.
على سبيل المثال، يمكن استخدام "عرض توضيحي" نكهة المنتج قد تحدد ميزات معينة
ومتطلبات الجهاز، مثل رمز المصدر المخصص والموارد والحد الأدنى
مستويات واجهة برمجة التطبيقات، في حين أن "تصحيح الأخطاء" يطبق نوع الإصدار تصميمًا مختلفًا
إعدادات الحزمة، مثل خيارات تصحيح الأخطاء ومفاتيح التوقيع. تشير رسالة الأشكال البيانية
إصدار متغير يجمع بين هذين الخيارين هو "demoDebug" من تطبيقك، ويتضمن
من الإعدادات والموارد المضمّنة في "العرض التوضيحي"
صيغة المنتج، "تصحيح الأخطاء" ونوع الإصدار، ومجموعة مصادر main/
.
ضبط أنواع الإصدارات
يمكنك إنشاء أنواع الإصدارات وضبطها داخل android
.
من ملف build.gradle.kts
على مستوى الوحدة. عند إنشاء
وحدة جديدة، يُنشئ استوديو Android تلقائيًا بنية تصحيح الأخطاء والإصدار
الأنواع. مع أنّ نوع إصدار تصحيح الأخطاء لا يظهر في إعدادات الإصدار.
يهيئه "استوديو Android" باستخدام debuggable
true
. يتيح لك ذلك تصحيح أخطاء التطبيق على أجهزة Android الآمنة
تضبط هذه السياسة توقيع التطبيق باستخدام ملف تخزين مفاتيح عام لتصحيح الأخطاء.
يمكنك إضافة نوع إصدار تصحيح الأخطاء إلى الإعدادات إذا كنت تريد إضافة
أو تغيير إعدادات معينة. يحدد النموذج التالي
applicationIdSuffix
لنوع الإصدار المخصّص لتصحيح الأخطاء وعمليات الإعداد
"مراحل" نوع الإصدار الذي تم إعداده باستخدام إعدادات نوع إصدار تصحيح الأخطاء:
Kotlin
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" } } }
Groovy
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 (المزامنة الآن).
في شريط الإشعارات الذي يظهر عند إجراء تغيير أو النقر
مزامنة المشروع من شريط الأدوات. إذا كان نظام التشغيل Android
ستلاحظ "استوديو YouTube" أي أخطاء في الإعدادات،
يبدو أنّ نافذة الرسائل تصف المشكلة.
لمزيد من المعلومات عن جميع المواقع التي يمكنك ضبطها باستخدام أنواع الإصدارات،
قراءة
مرجع BuildType
.
ضبط نكهات المنتجات
يتشابه إنشاء نكهات المنتج مع إنشاء أنواع التصميم. أضِف نكهات المنتجات إلى
productFlavors
في إعدادات تصميمك وتضمين الإعدادات التي تريدها.
نكهات المنتج تدعم نفس خصائص
defaultConfig
، لأن defaultConfig
ينتمي بالفعل إلى
الصف ProductFlavor
. وهذا يعني أنه يمكنك توفير الأساس
إعداد جميع النكهات في كتلة defaultConfig
يمكن لكل نكهة تغيير أي من هذه القيم التلقائية، مثل applicationId
. إلى
لمعرفة المزيد عن معرّف التطبيق، يمكنك قراءة
اضبط رقم تعريف التطبيق.
ملاحظة: لا يزال عليك تحديد اسم حزمة باستخدام السمة
package
في ملف البيان main/
. يجب عليك أيضًا استخدام ذلك
اسم الحزمة في رمز المصدر للإشارة إلى فئة R
أو لحل أي
النشاط النسبي أو تسجيل الخدمة. يتيح لك هذا استخدام
applicationId
لمنح كل نكهة منتج معرّفًا فريدًا
التغليف والتوزيع بدون الحاجة إلى تغيير رمز المصدر
يجب أن تنتمي جميع النكهات إلى سمة النكهة المسماة، وهي مجموعة من ونكهات المنتج. يجب تحديد كل النكهات لبُعد النكهة. وإلا، سيظهر خطأ الإصدار التالي.
Error: All flavors must now belong to a named flavor dimension. The flavor 'flavor_name' is not assigned to a flavor dimension.
إذا كانت هناك وحدة معينة تحدّد سمة صيغة واحدة فقط، سيحدّد المكوّن الإضافي لنظام Gradle المتوافق مع Android تلقائيًا وتعين كل صفات الوحدة لهذا البُعد.
ينشئ نموذج الرمز البرمجي التالي سمة صيغة باسم "version" وإضافة
"عرض توضيحي" و"كامل" ونكهات المنتج. توفر هذه النكهات الخاصة بها
applicationIdSuffix
و
versionNameSuffix
:
Kotlin
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" } } }
Groovy
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) التي توزّعها باستخدام حِزم APK على Google Play لتوزيع تطبيقك باستخدام حِزم APK متعددة
دعم في Google Play، يجب تخصيص قيمة applicationId
نفسها.
لكل خيارات المنتج ومنح كل خيار
versionCode
للتوزيع
صيغ مختلفة من تطبيقك باعتبارها تطبيقات منفصلة في Google Play، يجب تعيين
applicationId
لكل خيار منتج.
بعد إنشاء نكهات المنتجات وضبطها، انقر على مزامنة.
الآن في شريط الإشعارات. بعد اكتمال المزامنة، تُدرج أداة Gradle
تنشئ تلقائيًا صيغًا للتصميم استنادًا إلى أنواع التصميم والمنتج.
النكهات وتسميتها وفقًا
<product-flavor><Build-Type>
على سبيل المثال، إذا
تم إنشاء "عرض توضيحي" و"كامل" ونكهات المنتج، وحافظت على الإعداد
"تصحيح الأخطاء" أو
"إصدار" أنواع الإنشاء، تنشئ Gradle متغيرات التصميم التالية:
-
demoDebug
-
demoRelease
-
fullDebug
-
fullRelease
لتحديد صيغة الإصدار المطلوب إنشاؤها الجري، انتقل إلى إنشاء > اختَر صيغة الإصدار ثم انقر على متغير الإصدار من القائمة. لبدء تخصيص كل صيغة من صيغ الإصدار بميزاتها الخاصة الموارد، فستحتاج إلى إنشاء المستندات المصدر وإدارتها كما هو موضح في هذه الصفحة.
تغيير رقم تعريف التطبيق لصيغ الإصدار
عند إنشاء حزمة APK أو AAB لتطبيقك، تضع أدوات التصميم علامة على التطبيق مع
تم تحديد معرّف التطبيق في مجموعة defaultConfig
من build.gradle.kts
كما هو موضح في المثال التالي. ومع ذلك، إذا أردت إنشاء إصدارات مختلفة من
التطبيق كبيانات منفصلة على متجر Google Play، مثل "مجاني" و"pro"
تحتاج إلى إنشاء نسخة منفصلة
إنشاء صيغ لكلّ منها
معرّف التطبيق.
في هذه الحالة، عليك تحديد كل صيغة إصدار على أنّها نسخة منفصلة.
نكهة المنتج. لكل نكهة
داخل مجموعة productFlavors
، يمكنك إعادة تحديد applicationId
أو يمكنك بدلاً من ذلك إلحاق شريحة بمعرّف التطبيق التلقائي
باستخدام applicationIdSuffix
، كما هو موضح هنا:
Kotlin
android { defaultConfig { applicationId = "com.example.myapp" } productFlavors { create("free") { applicationIdSuffix = ".free" } create("pro") { applicationIdSuffix = ".pro" } } }
Groovy
android { defaultConfig { applicationId "com.example.myapp" } productFlavors { free { applicationIdSuffix ".free" } pro { applicationIdSuffix ".pro" } } }
بهذه الطريقة، سيتم تحديث معرّف التطبيق "المجاني" نكهة المنتج هي "com.example.myapp.free".
يمكنك أيضًا استخدام applicationIdSuffix
لإلحاق شريحة استنادًا إلى
نوع المبنى، كما هو موضح هنا:
Kotlin
android { ... buildTypes { getByName("debug") { applicationIdSuffix = ".debug" } } }
Groovy
android { ... buildTypes { debug { applicationIdSuffix ".debug" } } }
ولأنّ أداة Gradle تطبّق إعدادات نوع التصميم بعد استخدام نكهة المنتج، معرّف التطبيق "لتصحيح الأخطاء المجاني" صيغة الإصدار هي "com.example.myapp.free.debug". يكون هذا مفيدًا عندما تريد الحصول على كل من وأن يتم تثبيت الإصدار على الجهاز نفسه، لأنه لا يمكن لتطبيقين معرّف التطبيق نفسه.
في حال كان لديك تطبيق قديم (تم إنشاؤه قبل آب (أغسطس) 2021) التي توزّعها باستخدام حِزم APK على Google Play، وتريد استخدام بطاقة بيانات التطبيق نفسها من أجل توزيع حِزم APK متعددة يستهدف كل منها تهيئة جهاز مختلفة، مثل مستوى واجهة برمجة التطبيقات، ينبغي إذًا استخدام معرّف التطبيق نفسه لكل صيغة إصدار ولكن مع إدخال كل خيار حزمة APKversionCode
مختلفة. لمزيد من المعلومات، يُرجى الاطّلاع على
إتاحة عدة حِزم APK: جارٍ النشر
لا يتأثر استخدام تطبيقات AAB، لأنها تستخدم أداة واحدة تستخدم
رمز الإصدار ومعرّف التطبيق تلقائيًا.
ملاحظة: إذا كنت بحاجة إلى الإشارة إلى رقم تعريف التطبيق في
ملف البيان، فيمكنك استخدام العنصر النائب ${applicationId}
في أي
سمة البيان. خلال عملية إنشاء، تستبدل Gradle هذه العلامة بعلامة
معرّف التطبيق. لمزيد من المعلومات، يُرجى الاطّلاع على إدخال الإصدار
المتغيرات في البيان.
اجمع نكهات منتجات متعددة مع أبعاد النكهات
وفي بعض الحالات، قد تحتاج إلى دمج عمليات ضبط من منتجات متعددة ونكهات. على سبيل المثال، قد تحتاج إلى إنشاء عمليات ضبط مختلفة "كامل" و"نسخة تجريبية" نكهات المنتجات التي تستند إلى مستوى واجهة برمجة التطبيقات. للقيام بذلك، المكوّن الإضافي لنظام Gradle المتوافق مع Android إنشاء مجموعات متعددة من نكهات المنتجات كنكهة الأبعاد.
عند إنشاء تطبيقك، تجمع منصّة Gradle بين منتج إعداد الصيغة من كل سمة للنكهة التي تحدّدها، بالإضافة إلى إعدادات نوع الإصدار، لإنشاء صيغة الإصدار النهائية. لا تفعل Gradle تجمع نكهات المنتجات التي تنتمي إلى نفس بُعد النكهة.
يستخدم نموذج التعليمات البرمجية التالي
flavorDimensions
لإنشاء سمة "mode" النكهة
لتجميع قيم "الكامل" و"نسخة تجريبية" نكهات المنتج و"واجهة برمجة تطبيقات" النكهة
لتجميع إعدادات نكهة المنتج استنادًا إلى مستوى واجهة برمجة التطبيقات:
Kotlin
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" ... } } } ...
Groovy
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 كل صيغة من صيغ الإصدار أو العناصر المقابلة لها أو المنتج تظهر النكهات التي تنتمي إلى بُعد النكهة ذات الأولوية الأعلى أولاً، يليها ثم تلك التي تأتي من السمات ذات الأولوية الأقل، يليها نوع الإصدار.
استخدام تهيئة الإصدار السابق كمثال، تنشئ 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
بالإضافة إلى أدلة مجموعة المصادر، يمكنك إنشاء كل مستند على حدة
لنكهة المنتج وإنشاء صيغة، يمكنك أيضًا إنشاء أدلة مجموعة المصدر
لكل مجموعة من نكهات المنتجات. على سبيل المثال، يمكنك إنشاء
وإضافة مصادر Java إلى الدليل src/demoMinApi24/java/
،
وتستخدم Gradle هذه المصادر فقط عند إنشاء صيغة تجمع بين
نكهتي المنتج هاتين.
مجموعات المصادر التي تنشئها لإضفاء طابع خاص على المنتج تكون الأولوية أعلى من مجموعات المصادر التي تنتمي إلى كل مجموعة ونكهة المنتج الفردي. لمعرفة مزيد من المعلومات حول مجموعات المصادر وكيفية استخدام Gradle تدمج الموارد، فاطّلع على القسم الذي يتناول كيفية إنشاء مجموعات المصادر
فلترة الصيغ
تنشئ Gradle صيغة إصدار لكل مجموعة ممكنة من المنتج
النكهات وأنواع التصميم التي تقوم بتكوينها. ومع ذلك، قد يكون هناك بعض
وتنشئ متغيرات لا تحتاج إليها أو لا معنى لها في
سياق مشروعك. لإزالة بعض إعدادات صيغ الإصدارات، يُرجى اتّباع الخطوات التالية:
أنشِئ فلترًا لخيارات المنتج في build.gradle.kts
على مستوى الوحدة.
الملف.
وباستخدام إعدادات التصميم من القسم السابق كمثال،
لنفترض أنّك تخطط لاعتماد مستوى واجهة برمجة التطبيقات 23 والمستويات الأعلى فقط في الإصدار التجريبي.
من التطبيق. يمكنك استخدام صفحة
مجموعة واحدة (variantFilter
) لفلترة كل صيغة الإصدار
من الإعدادات التي تجمع بين "minApi21" و"نسخة تجريبية" نكهات المنتج:
Kotlin
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 } } } ...
Groovy
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 أي صيغ تصميم تتوافق مع
الشروط التي تحددها. لن تظهر صيغ الإصدار في القائمة بعد الآن
عندما تنقر على إنشاء > اختَر "صيغة الإصدار" من شريط القوائم.
أو إنشاء خيارات المنتج في
شريط نافذة الأداة.
إنشاء مجموعات مصادر
ينشئ "استوديو Android" تلقائيًا main/
مجموعة المصادر وأدلة
كل ما تريد مشاركته بين جميع صيغ التصميم. ومع ذلك،
إنشاء مجموعات مصادر جديدة للتحكم في الملفات التي تجمعها أداة Gradle
حزم لأنواع تصميمية معينة ونكهات منتجات ومجموعات من
نكهات المنتج (عند استخدام النكهة
السمات) وإنشاء صيغ.
على سبيل المثال، يمكنك تحديد أساسيات
الوظائف في مجموعة مصادر main/
واستخدام نكهة المنتج
مجموعات المصادر لتغيير العلامة التجارية لتطبيقك حسب العملاء المختلفين
تضمين أذونات خاصة ووظيفة تسجيل فقط لنُسخ الإصدارات
التي تستخدم نوع الإصدار المخصّص لتصحيح الأخطاء
تتوقع Gradle تنظيم ملفات وأدلة مجموعة المصدر بطريقة
بطريقة تشبه مجموعة المصدر main/
. على سبيل المثال، Gradle
ويتوقع ملفات Kotlin أو Java التابعة لفئة "تصحيح الأخطاء" نوع التصميم
الموجودة في الدليل src/debug/kotlin/
أو src/debug/java/
.
ويوفر المكوّن الإضافي لنظام Gradle المتوافق مع Android مهمة Gradle مفيدة تعرض كيفية تنظيم ملفاتك لكل نوع من أنواع الإنشاء أو والنكهات، وبناء المتغيرات. على سبيل المثال، العينة التالية من ناتج المهمة يصف المكان الذي تتوقع فيه Gradle العثور على ملفات معينة لعملية "تصحيح الأخطاء" بناء 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]
لعرض هذا الناتج، اتّبِع الخطوات التالية:
- انقر على Gradle في شريط نافذة الأدوات.
انتقل إلى MyApplication > المهام > android و انقر مرّتين على sourceSets.
لرؤية مجلد المهام، يجب السماح لنظام Gradle بإنشاء قائمة المهام أثناء المزامنة. ولإجراء ذلك، اتبع الخطوات التالية:
- انقر على ملف > الإعدادات > تجريبي (استوديو Android > الإعدادات > تجريبي على نظام التشغيل macOS).
- إلغاء اختيار عدم إنشاء قائمة مهام Gradle أثناء مزامنة Gradle.
- بعد تنفيذ Gradle للمهمة، يتم فتح النافذة Run لعرض الإخراج.
ملاحظة: تعرض لك نتائج المهام أيضًا كيفية تنظيم مجموعات المصادر.
عن الملفات التي تريد استخدامها لإجراء اختبارات لتطبيقك، مثل
test/
وandroidTest/
اختبار مجموعات مصادر
عند إنشاء نسخة جديدة من الإصدار، لا ينشئ "استوديو Android" المصدر
تعيين الأدلة لك، ولكنه يمنحك بعض الخيارات لمساعدتك. بالنسبة
على سبيل المثال، لإنشاء دليل java/
فقط لبرنامج "تصحيح الأخطاء"
نوع التصميم:
- افتح جزء المشروع واختَر عرض المشروع من القائمة أعلى الجزء.
- الانتقال إلى
MyProject/app/src/
- انقر بزر الماوس الأيمن على الدليل
src
واختَر جديد > الدليل. - من القائمة ضمن مجموعات مصادر Gradle، حدد full/java.
- اضغط على Enter.
ينشئ "استوديو Android" دليل مجموعة مصادر لنوع الإصدار المخصّص لتصحيح الأخطاء
ثم تنشئ دليل java/
بداخله. بدلاً من ذلك،
يمكن لـ Android Studio إنشاء الأدلة نيابةً عنك عند إضافة ملف جديد إلى
مشروعك لمتغير إصدار معين.
على سبيل المثال، لإنشاء ملف XML يضم قيمًا للدالة "debug" نوع التصميم:
- في لوحة المشروع، انقر بزر الماوس الأيمن على
src
. الدليل واختَر جديد > XML > ملف XML للقيم: - أدخِل اسم ملف XML أو احتفظ بالاسم التلقائي.
- من القائمة بجانب مجموعة المصادر المستهدفة، اختَر debug.
- انقر على إنهاء.
نظرًا لأن "تصحيح الأخطاء" نوع الإصدار على أنه مجموعة المصدر المستهدفة، وينشئ "استوديو Android" الأدلة اللازمة تلقائيًا عند تنشئ ملف XML. تبدو بنية الدليل الناتجة الشكل 1.
![](https://developer.android.com/static/images/tools/debug-directories_2-1_2x.png?authuser=9&hl=ar)
الشكل 1. أدلة مجموعة مصادر جديدة لبرنامج "تصحيح الأخطاء" بناء الكتابة.
وتحتوي مجموعات المصادر النشطة على مؤشر أخضر في رمزها للإشارة إلى أنها نشطة. تشير رسالة الأشكال البيانية
ستتم إضافة لاحقة [main]
إلى مجموعة المصادر debug
للإشارة إلى أنّه سيتم دمجها.
إلى مجموعة مصادر main
.
باستخدام الإجراء نفسه، يمكنك أيضًا إنشاء أدلة مجموعة مصادر
نكهات المنتجات، مثل src/demo/
، وتصميم خيارات مختلفة، مثل
src/demoDebug/
بالإضافة إلى ذلك، يمكنك إنشاء مجموعات مصادر اختبار
التي تستهدف صيغ تصميم محددة، مثل
src/androidTestDemoDebug/
لمزيد من المعلومات، يمكنك الاطّلاع على
مجموعات مصادر الاختبار.
تغيير إعدادات مجموعة المصادر التلقائية
إذا كانت لديك مصادر غير منظَّمة في ملف مجموعة المصادر التلقائي
الهيكل الذي تتوقعه غرادل، كما هو موضح في القسم السابق حول
إنشاء مجموعات مصادر، يمكنك استخدام
مربّع sourceSets
لتغيير مكان تجميع Gradle
لكل مكون في مجموعة مصدر.
يجب أن تكون القالب sourceSets
في الجزء android
. لا تحتاج إلى نقل
ملفات المصدر وإنما تحتاج فقط إلى تزويد Gradle بالمسار(المسارات)، نسبةً إلى
على مستوى الوحدة build.gradle.kts
حيث يمكن لـ Gradle
للعثور على الملفات لكل مكون من مكونات مجموعة المصدر. لمعرفة المكونات التي يمكنك
وما إذا كان يمكنك ربطها بملفات أو أدلة متعددة،
يُرجى الاطّلاع على مرجع واجهة برمجة تطبيقات المكوّن الإضافي لنظام Gradle المتوافق مع Android.
يربط نموذج الرمز التالي مصادر من الدليل app/other/
.
إلى مكونات معينة من مجموعة المصدر main
وتغيير
الدليل الجذري لمجموعة المصادر androidTest
:
Kotlin
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") ... } } ...
Groovy
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
. هذا النمط
لأنّ "استوديو Android" ينشئ وحدات IntelliJ منفصلة لكل مجموعة مصادر ولا يمكنه التوافق مع
جذور المحتوى المكررة عبر مجموعات المصادر.
الإنشاء باستخدام مجموعات المصادر
يمكنك استخدام أدلة مجموعة المصادر لتحتوي على التعليمات البرمجية والموارد التي نريد الحزمة مع تهيئات معينة فقط. على سبيل المثال، إذا كنت إنشاء "demoDebug" أي صيغة متقاطعة، وهي نتاج تبادلي "عرض توضيحي" صيغة المنتج و"تصحيح الأخطاء" نوع التصميم، فإن Gradle تظهر في هذه الأدلة وإعطائها الأولوية التالية:
-
src/demoDebug/
(إنشاء مجموعة مصادر الصيغ) -
src/debug/
(مجموعة مصادر نوع الإصدار) -
src/demo/
(مجموعة مصادر نكهة المنتج) -
src/main/
(مجموعة المصدر الرئيسية)
يجب أن تتضمّن مجموعات المصادر التي تمّ إنشاؤها لمجموعات نكهات المنتجات جميع سمات النكهات. على سبيل المثال، يجب أن تجمع مجموعة مصادر خيارات الإصدار ما بين نوع الإصدار وكل النكهة. الأبعاد. دمج التعليمات البرمجية والموارد التي تتضمن مجلدات تغطي عدة مجلدات ولكن ليس جميعها لا يمكن استخدام أبعاد النكهة.
إذا جمعت منتجات متعددة
النكهات، يتم تحديد الأولوية بين نكهات المنتج من خلال النكهة
التي تنتمي إليها. عند إدراج أبعاد النكهة مع
android.flavorDimensions
، ونكهات المنتجات التي
تنتمي إلى سمة النكهة الأولى التي تسردها، تكون لها أولوية أعلى من
وأولئك الذين ينتمون إلى بُعد النكهة الثانية، وهكذا. بالإضافة إلى ذلك،
مجموعات المصدر التي تقوم بإنشائها لمجموعات من نكهات المنتج لها
الأولوية عن مجموعات المصادر التي تنتمي إلى نكهة منتج فردي.
يحدد ترتيب الأولويات مجموعة المصادر التي تحتوي على
الأولوية عندما تجمع Gradle التعليمات البرمجية والموارد. لأنّ demoDebug/
من المحتمل أن يحتوي دليل مجموعة المصدر على ملفات خاصة بهذا الإصدار
الصيغة، إذا كان demoDebug/
يتضمن ملفًا تم تعريفه أيضًا في
debug/
، تستخدم Gradle الملف المتوفّر في demoDebug/
مجموعة المصدر. وبالمثل، تعطي Gradle الملفات في نوع التصميم ونكهة المنتج
المصدر يضبط أولوية أعلى من الملفات نفسها في 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
)، كما هو موضح في المثال التالي:
Kotlin
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.5.1") }
Groovy
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.5.1' }
لمزيد من المعلومات حول إعداد التبعيات، راجِع إضافة تبعيات الإصدار.
استخدام إدارة الاعتمادية الواعية لخيارات المنتجات
يتضمن الإصدار 3.0.0 من المكوّن الإضافي لنظام Gradle المتوافق مع Android والإصدارات الأحدث آلية تبعية جديدة تعمل تلقائيًا
تتطابق مع الصيغ عند استهلاك إحدى المكتبات. يعني هذا أنّ صيغة debug
للتطبيق
تستهلك تلقائيًا صيغة debug
للمكتبة، وهكذا. كما أنها تعمل عند استخدام
النكهات: سيؤدي صيغة freeDebug
للتطبيق إلى استهلاك freeDebug
للمكتبة.
المتغير.
لكي يتطابق المكوّن الإضافي بدقة مع خيارات المنتج، يجب: توفير إجراءات احتياطية مطابقة كما هو موضّح في في القسم التالي، في الحالات التي لا يمكن فيها إجراء مطابقة مباشرة.
على سبيل المثال، لنفترض أنّ تطبيقك يضبط نوع إصدار يُسمى "التقسيم المرحلي" ولكن أحد فإن تبعيات مكتبتها لا تعمل. عندما يحاول المكون الإضافي إنشاء "التقسيم المرحلي" نسخة من فلن يعرف إصدار المكتبة الذي يجب استخدامه، وستظهر لك رسالة خطأ مشابهة إلى ما يلي:
Error:Failed to resolve: Could not resolve project :mylibrary. Required by: project :app
حلّ أخطاء الإصدار المتعلّقة بمطابقة خيارات المنتج
يتضمن المكون الإضافي عناصر DSL لمساعدتك على التحكم في كيفية حل Gradle للمواقف في التي لا يمكن فيها إجراء تطابق مباشر بين التطبيق والتبعية.
في ما يلي قائمة بالمشاكل المتعلقة بمطابقة الاعتمادية الواعية للخيارات وكيفية إجراء ذلك لحلّها باستخدام خصائص DSL:يتضمّن تطبيقك نوع إصدار غير متوفّر في المكتبة التابعة لمكتبة.
على سبيل المثال، يتضمّن تطبيقك "تقسيمًا مرحليًا". ولكن التبعية تتضمن فقط "تصحيح الأخطاء" و"إصدار" وأنواع الإنشاءات.
لاحظ أنه ليست هناك مشكلة عندما تتضمن تبعية المكتبة إصدار النوع الذي لا يستخدمه تطبيقك. والسبب في ذلك هو أن المكون الإضافي لا للطلبات التي تنشئ نوعًا من التبعية.
استخدِم
matchingFallbacks
لتحديد مطابقات بديلة لنوع إصدار معيّن، كما هو موضح هنا:Kotlin
// 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") } } }
Groovy
// 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
لتحديد مطابقات بديلة للإصدار "المجاني" للتطبيق. نكهة المنتج، كما هو موضح هنا:Kotlin
// 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") } } }
Groovy
// 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" من والتبعية.
يمكنك استخدام
missingDimensionStrategy
في المجموعةdefaultConfig
لتحديد. الصيغة التلقائية للمكوّن الإضافي ليتم اختياره من كل بُعد مفقود، كما هو موضح في العينة التالية. يمكنك أيضًا إلغاء اختياراتك فيproductFlavors
. بحيث يمكن لكل نكهة تحديد استراتيجية مطابقة مختلفة لبُعد مفقود.Kotlin
// 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") {} } }
Groovy
// 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
في مرجع DSL لمكوّن Gradle المتوافق مع Android.
ضبط إعدادات التوقيع
لا يوقّع Gradle على ملف APK أو AAB لإصدار إصدارك ما لم تحدد بشكل صريح للتوقيع على إعدادات هذا الإصدار. إذا لم يكن لديك مفتاح توقيع حتى الآن، إنشاء مفتاح تحميل وملف تخزين مفاتيح باستخدام "استوديو Android".
لضبط إعدادات التوقيع يدويًا لنوع إصدار الإصدار باستخدام تهيئات إصدار Gradle:
- إنشاء ملف تخزين مفاتيح ملف تخزين المفاتيح هو ملف ثنائي يحتوي على مجموعة من المفاتيح الخاصة. يجب الاحتفاظ بملف تخزين المفاتيح في مكان آمن ومكان آمن.
- أنشئ مفتاحًا خاصًا. يتم استخدام مفتاح خاص لتوقيع تطبيقك. للتوزيع ولا يتم تضمينه في التطبيق أو الإفصاح عنه لجهات خارجية غير مصرَّح بها.
-
أضِف إعدادات التوقيع إلى
build.gradle.kts
على مستوى الوحدة. الملف:Kotlin
... android { ... defaultConfig {...} signingConfigs { create("release") { storeFile = file("myreleasekey.keystore") storePassword = "password" keyAlias = "MyReleaseKey" keyPassword = "password" } } buildTypes { getByName("release") { ... signingConfig = signingConfigs.getByName("release") } } }
Groovy
... android { ... defaultConfig {...} signingConfigs { release { storeFile file("myreleasekey.keystore") storePassword "password" keyAlias "MyReleaseKey" keyPassword "password" } } buildTypes { release { ... signingConfig signingConfigs.release } } }
ملاحظة: بما في ذلك كلمات مرور مفتاح الإصدار لا يُعد ملف تخزين المفاتيح داخل ملف الإصدار ممارسة أمنية جيدة. بدلاً من ذلك، يمكنك ضبط ملف الإصدار للحصول على كلمات المرور هذه. من متغيرات البيئة أو تطلب منك عملية الإصدار هذه كلمات المرور.
للحصول على كلمات المرور هذه من متغيرات البيئة:
Kotlin
storePassword = System.getenv("KSTOREPWD") keyPassword = System.getenv("KEYPWD")
Groovy
storePassword System.getenv("KSTOREPWD") keyPassword System.getenv("KEYPWD")
ويمكنك بدلاً من ذلك تحميل ملف تخزين المفاتيح من ملف المواقع الإلكترونية على الجهاز. لأسباب تتعلق بالأمان، لا لإضافة هذا الملف إلى عنصر التحكم في المصدر. وبدلاً من ذلك، يمكنك إعداده محليًا لكل مطور البرامج. لمزيد من المعلومات، يُرجى قراءة أزِل معلومات التوقيع من ملفات الإصدار.
بعد إكمال هذه العملية، يمكنك توزيع تطبيقك ونشره. على Google Play.
تحذير: احتفِظ بمفتاح تخزين المفاتيح والمفتاح الخاص في مكان آمن وموثوق به. مكان آمن والتأكّد من امتلاك نسخ احتياطية آمنة منها. في حال استخدام ميزة "توقيع التطبيق" من Play وتفقد مفتاح التحميل، يمكنك طلب إعادة الضبط باستخدام Play Console. في حال نشر تطبيق بدون ميزة "توقيع التطبيق" من Play (للتطبيقات التي تم إنشاؤها قبل آب/أغسطس 2021) ستفقد مفتاح توقيع التطبيق ولن تتمكّن من نشر أي تحديثات في تطبيقك لأنّك أن يوقّع دائمًا على جميع إصدارات تطبيقك باستخدام المفتاح نفسه.
توقيع تطبيقات Wear OS
عند نشر تطبيقات Wear OS، يجب توقيع كل من حزمة APK للساعة الذكية وحِزمة APK الاختيارية للهاتف باستخدام نفس المفتاح. لمزيد من المعلومات حول حزمة تطبيقات Wear OS وتوقيعها، يمكنك الاطّلاع على حزم تطبيقات Wear وتوزيعها