Android multi-channel packaging read this one is enough

Three processes in this paper

1. Multi-channel configuration

1. Multi-channel configuration
2. Different signature configurations for different channels
3. Configuration of different resource files in different channels
4. Different channels have different dependency configurations

Two, matters needing attention

Three, packaging,

1, command line packaging

2, IDE packaging

Multi-channel configuration (two methods)

1, can be written in the main module (APP) build.gradle

android {  
  compileSdkVersion 29  
  buildToolsVersion "29.0.3"  
  
  defaultConfig {  
	  applicationId "com.test.moduledemo"  
	  minSdkVersion 21  
	  targetSdkVersion 29  
	  versionCode 1  
	  versionName "1.0"  
  }  
  
  flavorDimensions "versionCode"ProductFlavors {xiaomi{applicationId = "com.test. Xiaomi"// Different channels with different parameters buildConfigField"int","TEST_VALUE","1" buildConfigField "String","TEST_NAME","\"xiaomi\""  
	  }  
	  huawei{  
	  	  applicationId = "com.test.huawei"  
		  // Configure different parameters for different channels
		  buildConfigField "int"."TEST_VALUE"."2"  
		  buildConfigField "String"."TEST_NAME"."\"huawei\""  
	  }	    
	  productFlavors.all {// productFlavors multiple options, setting the "xiaomi, Huawei" option
		  flavor -> flavor.manifestPlaceholders.put("CHANNEL", name)  
	  }
  }
  applicationVariants.all { variant ->  
	  // Output the path after packaging is complete
	  defname = ((project.name ! ="app")? project.name : rootProject.name.replace(""."")) + 
	  "_" + variant.flavorName + 
	  "_" + variant.buildType.name + 
	  "_" + variant.versionName + 
	  "_" + new Date().format('yyyyMMddhhmm') + ".apk"  
      / / relative path app/build/outputs/apk/huawei/release /
      def path = ".. /.. /.. /.. /.. /apk/" // Equivalent to the path app/apk/
      variant.outputs.each { output ->
          def outputFile = output.outputFile
          if(outputFile ! =null && outputFile.name.endsWith('.apk')) {
               // Specify path output
               output.outputFileName = new File(path, name)
          }
      } 
	  // There are other things you can do after the packaging is complete, you can copy to the specified directory, or move the file to the specified directory
	  variant.assemble.doLast {  
		  File out = newElsiders.txt File(" ${project.rootdir}/apk ") variable. outputs.// Copy apk to the specified folder
			//copy {  
			//	from file.outputFile  
			//	into out  
			/ /}
		 // Move the file to the specified folder
		  ant.move file: file.outputFile,  
                 todir: "${project.rootDir}/apk"}}}// Configure multi-channel signature
  signingConfigs {
	 test {
        storeFile file(".. /test.keystore")
        storePassword 'test'
        keyAlias 'test'
        keyPassword 'test'
        v1SigningEnabled true
        v2SigningEnabled true
     }
     xiaomi {
        storeFile file(".. /xiaomi.keystore")
        storePassword 'xiaomi'
        keyAlias 'xiaomi'
        keyPassword 'xiaomi'
        v1SigningEnabled true
        v2SigningEnabled true
     }
     huawei {
        storeFile file(".. /huawei.keystore")
        storePassword 'huawei'
        keyAlias 'huawei'
        keyPassword 'huawei'
        v1SigningEnabled true
        v2SigningEnabled true
     }
  }
  buildTypes {
       debug {
// debug this setting does not work.
// productFlavors.xiaomi.signingConfig signingConfigs.test
// productFlavors.huawei.signingConfig signingConfigs.test
       }
       release {
	       productFlavors.xiaomi.signingConfig signingConfigs.xiaomi
	       productFlavors.huawei.signingConfig signingConfigs.huawei
       }
  }
// Different channel different resource file configuration
  sourceSets{
	  xiaomi.res.srcDirs 'src/main/res-xiaomi'
      huawei.res.srcDirs 'src/main/res-huawei'
  }
// Different channels have different dependency files
  dependencies {
	  xiaomiApi('xxxxxxx')
	  huaweiImplementation('xxxxxxxx')}}Copy the code

Create an flavors. Gradle file in the root directory of the project (same directory as settings.gradle)

 android {  
  flavorDimensions "versionCode"  
  
  productFlavors {  
	  xiaomi{ 
	  applicationId = "com.test.xiaomi"   
		  // Configure different parameters for different channels
		  buildConfigField "int"."TEST_VALUE"."1"  
		  buildConfigField "String"."TEST_NAME"."\"xiaomi\""  
	  }  
	  huawei{  
	   applicationId = "com.test.huawei"  
		  // Configure different parameters for different channels
		  buildConfigField "int"."TEST_VALUE"."2"  
		  buildConfigField "String"."TEST_NAME"."\"huawei\""  
	  } 
	  productFlavors.all {// productFlavors multiple options, setting the "xiaomi, Huawei" option
		  flavor -> flavor.manifestPlaceholders.put("CHANNEL", name)  
	  } 
  }
 / /... More configuration
 }
Copy the code

Gradle file(‘flavors. Gradle ‘) on the build.gradle file of the main module

Pay attention to

If the project is more complex, it may be possible to set different channel packages with buildConfigField, and different information fields may fail, Put (“TEST_VALUE”, 1) and add it to androidManifest.xml

<application>
	<meta-data  
	  android:name="TEST_VALUE"  
	  android:value="${TEST_VALUE}" />
</application> 
Copy the code

Get its value in code by doing the following:

ApplicationInfo applicationInfo = getPackageManager().getApplicationInfo(getPackageName(),  
  PackageManager.GET_META_DATA);
  int testValue = applicationInfo.metaData.getInt("TEST_VALUE");
Copy the code

packaging

Command line packaging:

Gradlew assembleRelease for Windows . / gradlew assembleRelease assembleRelease is playing all channel Release package assembleDebug is playing the Debug packages of all channels You can specify the channel package: Gradlew assembleXiaoMiRelease assembleHuaWeiRelease

Compiler packaging

When there are a lot of channels, different configurations for different channels can become quite tedious, so please check out my next tweetMulti-channel packaging – Advanced