When developing an application, the basic functions are the same. When packaging, distinguish channels, configure different package names and signatures.
1. Create a new project
Simply create a default Hello World project.
2. Create a new folder for the corresponding channel
Create a new folder qudao1 in the src directory, and then generate the same directory as the main file. Only the directory is needed, and the files in each directory are not needed first.
(this chapter mainly focuses on configuration without changing the code)
Create a new folder qudao2 in the src directory. The operation is the same as creating qudao1.
To distinguish, we simply modify the string xml ,
Under main,
<resources> <string name="app_name">OneAppMutilBale</string> </resources>
qudao1,
<resources> <string name="app_name">OneAppMutilBaleQudao1</string> </resources>
qudao2,
<resources> <string name="app_name">OneAppMutilBaleQudao2</string> </resources>
3. Configure build gradle
Modify the build.of app gradle ,
Add sourceSets {} to indicate the folder used by each module. To add this, you need to configure the flavorDimensions "app". Otherwise, an error is reported, and the app can be replaced with another name.
Add productFlavors {}, specify the channel, and configure the package name and version number according to the channel.
Just name the base, qudao1 and qudao2.
dimension corresponds to flavorDimensions
plugins { id 'com.android.application' } android { compileSdkVersion 30 defaultConfig { applicationId "com.cosmos.oneappmutilbale" minSdkVersion 23 targetSdkVersion 30 versionCode 1 versionName "1.0" flavorDimensions "app" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } sourceSets { base { java.srcDir('src/main/java') res.srcDir('src/main/res') // assets.srcDir('src/main/assets') // manifest.srcFile('src/main/AndroidManifest.xml') } qudao1 { java.srcDir('src/qudao1/java') res.srcDir('src/qudao1/res') // assets.srcDir('src/qudao1/assets') // manifest.srcFile('src/qudao1/AndroidManifest.xml') } } } productFlavors { base { applicationId "com.cosmos.oneappmutilbale" dimension "app" versionCode 1 versionName "1.0" } qudao1 { applicationId "com.cosmos.oneappmutilbale.q1" dimension "app" versionCode 1 versionName "1.1" } } applicationVariants.all { variant -> variant.outputs.all { outputFileName = "OneAppMutilBale_${variant.productFlavors[0].name}_v${variant.productFlavors[0].versionName}.apk" } } } dependencies { implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'com.google.android.material:material:1.2.1' implementation 'androidx.constraintlayout:constraintlayout:2.0.1' testImplementation 'junit:junit:4.+' androidTestImplementation 'androidx.test.ext:junit:1.1.2' androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' }
applicationVariants. The all {} section specifies the name of the generated apk.
Synchronize. If multiple choices appear in the build variables column, it indicates that it is successful.
4. Configure different channel signatures
Generate multiple jks signatures through AS. (specific process omitted)
I created a jks directory to store jks signature files.
Modify the build.of app gradle ,
Add signingConfigs {}, indicating jks path and password. Just name the signbase, signqudao1 and signqudao2.
plugins { id 'com.android.application' } android { compileSdkVersion 30 defaultConfig { applicationId "com.cosmos.oneappmutilbale" minSdkVersion 23 targetSdkVersion 30 versionCode 1 versionName "1.0" flavorDimensions "app" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } sourceSets { base { java.srcDir('src/main/java') res.srcDir('src/main/res') // assets.srcDir('src/main/assets') // manifest.srcFile('src/main/AndroidManifest.xml') } qudao1 { java.srcDir('src/qudao1/java') res.srcDir('src/qudao1/res') // assets.srcDir('src/qudao1/assets') // manifest.srcFile('src/qudao1/AndroidManifest.xml') } qudao2 { java.srcDir('src/qudao2/java') res.srcDir('src/qudao2/res') // assets.srcDir('src/qudao2/assets') // manifest.srcFile('src/qudao2/AndroidManifest.xml') } } signingConfigs { signbase { storeFile file("src/jks/main.jks") storePassword "123456" keyAlias "keymain" keyPassword "123456" // Open V2 signature v2SigningEnabled true } signqudao1 { storeFile file("src/jks/qudao1.jks") storePassword "789456" keyAlias "keyqudao1" keyPassword "789456" v2SigningEnabled true } signqudao2 { storeFile file("src/jks/qudao2.jks") storePassword "456123" keyAlias "keyqudao2" keyPassword "456123" v2SigningEnabled true } } productFlavors { base { applicationId "com.cosmos.oneappmutilbale" dimension "app" versionCode 1 versionName "1.0" signingConfig signingConfigs.signbase } qudao1 { applicationId "com.cosmos.oneappmutilbale.q1" dimension "app" versionCode 1 versionName "1.1" signingConfig signingConfigs.signqudao1 } qudao2 { applicationId "com.cosmos.oneappmutilbale.q2" dimension "app" versionCode 2 versionName "2.0" signingConfig signingConfigs.signqudao2 } } applicationVariants.all { variant -> variant.outputs.all { outputFileName = "OneAppMutilBale_${variant.productFlavors[0].name}_v${variant.productFlavors[0].versionName}.apk" } } } dependencies { implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'com.google.android.material:material:1.2.1' implementation 'androidx.constraintlayout:constraintlayout:2.0.1' testImplementation 'junit:junit:4.+' androidTestImplementation 'androidx.test.ext:junit:1.1.2' androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' }
I use different signatures here. The generated apk signature must be different. How to verify?
After build, apks of multiple channels will be generated in the app/build/outputs/apk / directory. Use the following command in the Terminal column to view the apk signature,
keytool -printcert -jarfile apk_path
apk_path is the path of APK.
The corresponding results of apk s of the three channels are different, indicating that different signatures have been configured.
5. Installation verification
The applications of the three channels have different package names and can be installed on the same machine. Corresponding app_name is different.