This blog mainly for my learning process summary, there are wrong place trouble point out, study together progress

preface

Recently also got an ebook “Android+Gradle authoritative guide”, learn a wave of Gradle knowledge, try to configure signature Settings and configure Walle to achieve multi-channel packaging. Reading time: 15 minutes

The signature

View mode

We can do this by clicking Build->Generate Signed APK->Next in the upper left corner. If you do not have a JKS file, you need to create your own, and then select the corresponding Build Type to package.

For some apps that don’t need to be listed, this operation is acceptable, but if you need to upload it to various domestic platforms, you need to repeat this operation several times, which can kill people… In this article, you can learn Gradle signature configuration and Walle configuration internship multi-channel packaging.

Gradle configures signatures

Let’s take a look at the default configuration of the app Gradle file for the new project.

  1. The preparatory work

First, put the generated JKS file into the project directory

  1. Modify the app build. Gradle
defaultConfig { .... } signingConfigs {release {storeFilefile(../ymcandroid.jks)// Path to the signature file storePassword ymc****** keyAlias key0 keyPassword ymc******/Sign/password println (" = = = = = = signingConfigs. Release the = = = = = = ")}}Copy the code

Some of the variables in the above code correspond to the JKS file information that we need to add to the view packaging.

  • Could not find property ‘debugConfig’ on SigningConfig Container
  1. Package the Release APK package

We can see our packaged APK in app/build/outputs under the project path.

Here’s my buildTypes configuration

buildTypes {
        release {
            minifyEnabled false
            // Determine whether to remove unnecessary resources
            zipAlignEnabled true
            signingConfig signingConfigs.release
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}}Copy the code

The above is a simple signature, but my wanAndroid project needs to be uploaded to Github, so let’s talk about ignoring files first. When uploading git, we will ignore some files. The following is the configuration of ignoring files in my project

# Built application files //
*.apk
*.ap_
# Files for the ART/Dalvik VM
*.dex
# Java class files
*.class
# Generated files
bin/
gen/
out/
# Gradle files
.gradle/
build/
# Local configuration file (sdk path, etc)
local.properties
/local.properties
# Proguard folder generated by Eclipse
proguard/
# Log Files
*.log
# Android Studio Navigation editor temp files
.navigation/
# Android Studio captures folder
captures/
# Intellij
*.iml
.idea/workspace.xml
# Keystore files
*.jks

*.iws
.idea/
Copy the code

Here we can find the local.properties file where we will configure the JKS password information.

ndk.dir=E\:\\AndroidSDK\\ndk-bundle
sdk.dir=E\:\\AndroidSDK

keystore.path=../ymcandroid.jks
keystore.password=ymc******
keystore.alias=key0
keystore.alias_password=ymc******
Copy the code

In this case, we need to modify the app build.gradle file to replace the plain text

def keystoreFilepath = ' '
def keystorePSW = ' '
def keystoreAlias = ' '
def keystoreAliasPSW = ' '
// default keystore file, PLZ config file path in local.properties
def keyfile = file('s.keystore.temp')

Properties properties = new Properties()
// local.properties file in the root director
properties.load(project.rootProject.file('local.properties').newDataInputStream())
keystoreFilepath = properties.getProperty("keystore.path")

if (keystoreFilepath) {
    keystorePSW = properties.getProperty("keystore.password")
    keystoreAlias = properties.getProperty("keystore.alias")
    keystoreAliasPSW = properties.getProperty("keystore.alias_password")
    keyfile = file(keystoreFilepath)
}

android {
    compileSdkVersion 27
    defaultConfig {
        applicationId "cn.white.ymc.wanandroidmaster"
        minSdkVersion 19
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        vectorDrawables.useSupportLibrary = true
    }

    signingConfigs {
        release {
            storeFile keyfile// The signature file path
            storePassword keystorePSW
            keyAlias keystoreAlias
            keyPassword keystoreAliasPSW  // The signature password
            println("====== signingConfigs.release ======")
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            // Determine whether to remove unnecessary resources
            zipAlignEnabled true
            signingConfig signingConfigs.release
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            // If the signature file exists, sign the file
            if (keyfile.exists()) {
                println("WITH -> buildTypes -> release: using jks key")
                signingConfig signingConfigs.release
            }else {
                println("WITH -> buildTypes -> release: using default key")}}}}dependencies{... }Copy the code

The main change is to use gradle syntax to read the local.properties file, get the information in it, and sign and package it if there is any. This way we can keep the key file secure.

After talking about signature, we need to look at Walle configuration and some Gradle related operations.

Walle packaging

Why use Meituan multi-channel package

The traditional productFlavors channel package is acceptable for less than 10 channels. If there are 100 channels, people will die. But meituan Walle multi-channel package only needs one package time. Flexible configuration You can configure the config file in the APK channel package to customize additional information for different channel packages.

The principle of

The entire APK (ZIP file format) is divided into the following four blocks:

Contents of ZIP entries (from offset 0 until the start of APK Signing Block) APK Signing Block ZIP Central Directory ZIP End of Central Directory

This is the APK package format of the V2 signature package. The new application signature scheme has good backward compatibility and is fully compatible with Android versions below 7.0 (Nougat). Blocks 1, 3, and 4 are protected blocks and no modification of protected blocks is allowed. Meituan’s packaging method is to write the extended information (channel information) of ID-value in block 2 and save it in APK. In this way, you only need to copy one APK per dozen channel packages and add an ID-value to the APK.

Walle configuration

Add dependencies for the Walle Gradle plugin to the build.gradle file in the project root directory

The classpath 'com. At meituan. Android. Walle: plugin: 1.1.6'Copy the code

App build.gradle file apply this plugin and add the AAR to read channel numbers

Apply the plugin: 'walle' dependencies {the compile 'com. At meituan. Android. Walle: library: 1.1.6'}Copy the code

Let’s create a new gradle to save the configuration plugin Multlple -channel.gradle

apply plugin: 'walle'

walle {
    // Specify the output path of the channel package
    apkOutputFolder = new File("${project.buildDir}/outputs/channels")
    // Customize the file name of the channel pack APK
    apkFileNameFormat = '${appName}-${channel}-${buildType}-v${versionName}-${versionCode}-${buildTime}.apk';
    // Channel configuration file
    channelFile = new File("${project.getProjectDir()}/channel")}Copy the code

Partial configuration resolution

ApkOutputFolder: specify the output of the channel package path, the default value is the new File (” project. The buildDir/outputs/apk) apkFileNameFormat: {project. BuildDir}/outputs/ APK “) Custom channel package APK file name, the default value for the project. The buildDir/outputs/APK) apkFileNameFormat: “” APK file name of the custom channel package. The default value is {appName}- buildType−{buildType}-buildType−{channel}.apk

Variable meaning

ProjectName – projectName

AppName - App module name packageName - applicationId (App packageName packageName) buildType - buildType (release/debug) channel - Channel name (the channel name in the channel package) versionname-VersionName (the version number for display) versioncode-VersionCode (the internal version number) buildTime - buildTime FlavorName - flavorName of fileSHA1 - fileSHA1 (final APK fileSHA1 hash) flavorName - productFlavorsCopy the code

Be sure to include it in your app build.gradle file after you finish adding it

apply from: 'multlple-channel.gradle'
Copy the code

Next, configure channelFile

Meituan # Samsungapps # Samsung Hiapk anzhi Xiaomi # Mi91com gfan AppChina nduoa 3gcn mumayi 10086com wostore 189store Lenovomm Hicloud Meizu Wandou # Google Play # GooglePlay # Baidu Baidu # # 360 360cn # # App MyAppCopy the code

For the above market platforms, readers can cut down to what they need, and then we use Android Studio to package it

Packaging will take a while, and when it is successful, we will open the configuration output addressYou can see the installation packages we need for each channel.

Reference blog: Walle Github Android Studio Signature