عند العمل على مشروع Android ، وهو نظام أساسي لإنشاء تطبيقات لعرض محتوى الفيديو ، أصبح من الضروري تكوين نكهات المنتج ديناميكيًا بنقل المعلومات حول توقيع التهيئة إلى ملف خارجي. التفاصيل تحت خفض.
مصدر البيانات
يوجد مشروع Android ، وهو عبارة عن منصة لإنشاء تطبيقات لعرض محتوى الفيديو. قاعدة الكود شائعة لجميع التطبيقات ، والاختلافات موجودة في إعدادات معلمات واجهة برمجة تطبيقات REST ومظهر التطبيق (الشعارات والألوان والخطوط وغيرها). تم استخدام ثلاثة أبعاد نكهة في المشروع:
- السوق : جوجل أو الأمازون. بسبب يتم توزيع التطبيقات على كل من Google Play وفي Amazon Marketplace ، وهناك حاجة إلى مشاركة بعض الوظائف حسب مكان التوزيع. على سبيل المثال: تحظر Amazon استخدام آلية مشتريات داخل التطبيق من Google وتتطلب تنفيذ آليتها.
- نقطة النهاية : "الموالية" أو "التدريج". تكوينات محددة للإنتاج والتدريج الإصدارات.
- الموقع : البعد الفعلي لتطبيق معين. قم بتعيين applicationId و signConfig.
المشاكل التي واجهناها
عند إنشاء تطبيق جديد ، كان من الضروري إضافة نكهة المنتج:
application1 { dimension 'site' applicationId 'com.damsols.application1' signingConfig signingConfigs.application1 }
أيضًا ، كان من الضروري إضافة تهيئة التوقيع المناسبة:
application1 { storeFile file("path_to_keystore1.jks") storePassword "password1" keyAlias "application1" keyPassword "password1" }
المشاكل:
- خمسة أسطر لإضافة تطبيق واحد ، تختلف فقط في applicationId و signConfig. عندما أصبح عدد التطبيقات أكثر من 50 ، بدأ ملف build.gradle في احتواء أكثر من 500 سطر من معلومات التطبيق.
- تخزين في معلومات النص العادي حول keystore لتوقيع التطبيقات.
مثال بناء apply plugin: 'com.android.application' android { compileSdkVersion 28 defaultConfig { minSdkVersion 23 targetSdkVersion 28 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false } } flavorDimensions "site", "endpoint", "market" signingConfigs { application1 { storeFile file("application1.jks") storePassword "password1" keyAlias "application1" keyPassword "password1" } application2 { storeFile file("application2.jks") storePassword "password2" keyAlias "application2" keyPassword "password2" } application3 { storeFile file("application3.jks") storePassword "password3" keyAlias "application3" keyPassword "password3" } } productFlavors { pro { dimension 'endpoint' } staging { dimension 'endpoint' } google { dimension 'market' } amazon { dimension 'market' } application1 { dimension 'site' applicationId "com.damsols.application1" signingConfig signingConfigs.application1 } application2 { dimension 'site' applicationId "com.damsols.application2" signingConfig signingConfigs.application2 } application3 { dimension 'site' applicationId "com.damsols.application3" signingConfig signingConfigs.application3 } } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'com.android.support:appcompat-v7:28.0.0' implementation 'com.android.support.constraint:constraint-layout:1.1.3' }
كانت الخطوة الأولى هي نقل معلومات الشهادة إلى ملف json منفصل. على سبيل المثال ، يتم تخزين المعلومات أيضًا بنص عادي ، لكن لا شيء يمنعك من تخزين الملف في نموذج مشفر (نستخدم GPG) وفك تشفيره مباشرة أثناء إنشاء التطبيق. يحتوي ملف JSON على البنية التالية:
{ "signingConfigs":[ { "configName":"application1", "storeFile":"application1.jks", "storePassword":"password1", "keyAlias":"application1", "keyPassword":"password1" }, { "configName":"application2", "storeFile":"application2.jks", "storePassword":"password2", "keyAlias":"application2", "keyPassword":"password2" }, { "configName":"application3", "storeFile":"application3.jks", "storePassword":"password3", "keyAlias":"application3", "keyPassword":"password3" }, ] }
يتم حذف المقطع signConfigs في ملف build.gradle.
تبسيط أقسام نكهات المنتج
لتقليل عدد الأسطر المطلوبة لوصف Product Flavor مع البعد = "site" ، تم إنشاء صفيف بالمعلومات اللازمة لوصف التطبيق المحدد ، وتم حذف جميع نكهات المنتج ذات البعد = "site".
كان:
... productFlavors { pro { dimension 'endpoint' } staging { dimension 'endpoint' } google { dimension 'market' } amazon { dimension 'market' } application1 { dimension 'site' applicationId "com.damsols.application1" signingConfig signingConfigs.application1 } application2 { dimension 'site' applicationId "com.damsols.application2" signingConfig signingConfigs.application2 } application3 { dimension 'site' applicationId "com.damsols.application3" signingConfig signingConfigs.application3 } } } ...
أصبح:
... productFlavors { pro { dimension 'endpoint' } staging { dimension 'endpoint' } google { dimension 'market' } amazon { dimension 'market' } } def applicationDefinitions = [ ['name': 'application1', 'applicationId': 'com.damsols.application1'], ['name': 'application2', 'applicationId': 'com.damsols.application2'], ['name': 'application3', 'applicationId': 'com.damsols.application3'] ] } ...
خلق نكهات المنتج الديناميكي
كانت الخطوة الأخيرة هي إنشاء نكهات المنتجات بشكل ديناميكي وتوقيع التهيئة باستخدام ملف JSON خارجي بمعلومات الشهادة من صفيف applicationDefinitions.
def applicationDefinitions = [ ['name': 'application1', 'applicationId': 'com.damsols.application1'], ['name': 'application2', 'applicationId': 'com.damsols.application2'], ['name': 'application3', 'applicationId': 'com.damsols.application3'] ] def signKeysFile = file('signkeys/signkeys.json') def signKeys = new JsonSlurper().parseText(signKeysFile.text) def configs = signKeys.signingConfigs def signingConfigsMap = [:] configs.each { config -> signingConfigsMap[config.configName] = config } applicationDefinitions.each { applicationDefinition -> def signingConfig = signingConfigsMap[applicationDefinition['name']] android.productFlavors.create(applicationDefinition['name'], { flavor -> flavor.dimension = 'site' flavor.applicationId = applicationDefinition['applicationId'] flavor.signingConfig = android.signingConfigs.create(applicationDefinition['name']) flavor.signingConfig.storeFile = file(signingConfig.storeFile) flavor.signingConfig.storePassword = signingConfig.storePassword flavor.signingConfig.keyAlias = signingConfig.keyAlias flavor.signingConfig.keyPassword = signingConfig.keyPassword }) }
لإضافة قراءة من التخزين المشفر ، تحتاج إلى استبدال القسم
def signKeysFile = file('signkeys/signkeys.json') def signKeys = new JsonSlurper().parseText(signKeysFile.text) def configs = signKeys.signingConfigs
لقراءة من ملف مشفر.
build.gradle كله import groovy.json.JsonSlurper apply plugin: 'com.android.application' android { compileSdkVersion 28 defaultConfig { minSdkVersion 23 targetSdkVersion 28 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false } } flavorDimensions "site", "endpoint", "market" signingConfigs {} productFlavors { pro { dimension 'endpoint' } staging { dimension 'endpoint' } google { dimension 'market' } amazon { dimension 'market' } } } def applicationDefinitions = [ ['name': 'application1', 'applicationId': 'com.damsols.application1'], ['name': 'application2', 'applicationId': 'com.damsols.application2'], ['name': 'application3', 'applicationId': 'com.damsols.application3'] ] def signKeysFile = file('signkeys/signkeys.json') def signKeys = new JsonSlurper().parseText(signKeysFile.text) def configs = signKeys.signingConfigs def signingConfigsMap = [:] configs.each { config -> signingConfigsMap[config.configName] = config } applicationDefinitions.each { applicationDefinition -> def signingConfig = signingConfigsMap[applicationDefinition['name']] android.productFlavors.create(applicationDefinition['name'], { flavor -> flavor.dimension = 'site' flavor.applicationId = applicationDefinition['applicationId'] flavor.signingConfig = android.signingConfigs.create(applicationDefinition['name']) flavor.signingConfig.storeFile = file(signingConfig.storeFile) flavor.signingConfig.storePassword = signingConfig.storePassword flavor.signingConfig.keyAlias = signingConfig.keyAlias flavor.signingConfig.keyPassword = signingConfig.keyPassword }) } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'com.android.support:appcompat-v7:28.0.0' implementation 'com.android.support.constraint:constraint-layout:1.1.3' }
جيثب لينك
شكرا لك