Android:動的な製品フレーバーの作成と構成の署名

ビデオコンテンツを表示するためのアプリケーションを作成するためのプラットフォームであるAndroidプロジェクトで作業する場合、署名設定に関する情報を外部ファイルに転送して製品フレーバーを動的に設定する必要がありました。 カットの下の詳細。







ソースデータ



ビデオプロジェクトを表示するためのアプリケーションを作成するためのプラットフォームであるAndroidプロジェクトがあります。 コードベースはすべてのアプリケーションに共通しており、違いはREST APIパラメーターの設定とアプリケーションの外観(バナー、色、フォントなど)の設定にあります。 プロジェクトでは3つのフレーバーディメンションが使用されました。







  1. 市場 :グーグルまたはアマゾン。 なぜなら アプリケーションはGoogle PlayとAmazon Marketplaceの両方で配布されるため、配布場所に応じていくつかの機能を共有する必要があります。 例:Amazonは、Googleによるアプリ内購入メカニズムの使用を禁止しており、そのメカニズムの実装を要求しています。
  2. エンドポイント :「プロ」または「ステージング」。 実動バージョンとステージングバージョンの特定の構成。
  3. サイト :特定のアプリケーションの実際の寸法。 applicationIdおよびsigningConfigを設定します。


遭遇した問題



新しいアプリケーションを作成するとき、製品フレーバーを追加する必要がありました。







application1 { dimension 'site' applicationId 'com.damsols.application1' signingConfig signingConfigs.application1 }
      
      





また、適切な署名構成を追加する必要がありました。







 application1 { storeFile file("path_to_keystore1.jks") storePassword "password1" keyAlias "application1" keyPassword "password1" }
      
      





問題は次のとおりです。



  1. applicationIdとsigningConfigのみが異なる1つのアプリケーションを追加するための5行。 アプリケーション数が50を超えると、build.gradleファイルには500行を超えるアプリケーション情報が含まれるようになりました。
  2. アプリケーションに署名するためのキーストアに関するプレーンテキスト情報のストレージ。


Build.gradleの例
 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" }, ] }
      
      





build.gradleファイルのsigningConfigsセクションが削除されます。







製品フレーバーセクションの簡素化



ディメンション= "サイト"の製品フレーバーを記述するために必要な行数を減らすために、特定のアプリケーションを記述するために必要な情報を含む配列が作成され、ディメンション= "サイト"のすべての製品フレーバーが削除されました。

それは:







 ... 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'] ] } ...
      
      





製品フレーバーの動的作成



最後のステップは、applicationDefinitions配列からの証明書情報を含む外部JSONファイルを使用して、製品フレーバーと署名構成を動的に作成することでした。







 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' }
      
      





GitHubリンク







よろしくお願いします!








All Articles