gradle packaging script

gradle packaging script

1. Different closure meanings

defaultConfig{} Default configuration, yes ProductFlavor Type. Share it with others ProductFlavor use sourceSets{ } Source file directory settings, yes AndroidSourceSet Type.
buildTypes{ } BuildType type
signingConfigs{ } Signature configuration, SigningConfig type
productFlavors{ } Product style configuration, ProductFlavor type
testOptions{ } Test configuration, TestOptions type
aaptOptions{ } aapt to configure, AaptOptions type
lintOptions{ } lint to configure, LintOptions type
dexOptions{ } dex to configure, DexOptions type
compileOptions{ } Compile configuration, CompileOptions type
packagingOptions{ } PackagingOptions type
jacoco{ } JacocoExtension Type. Used to set jacoco edition
splits{ } Splits type

2 configuration signature

2.1 create a keystore folder under the project root path and put the. store or. jks file into the

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-jbjuwr1y-1631589117624) (C: \ users \ Lenovo \ appdata \ roaming \ typora user images \ image-20210914102048356. PNG)]

2.2 create the key.properties file under the project root path and write the information of the signature file to the

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-s4qgw6ta-1631589117625) (C: \ users \ Lenovo \ appdata \ roaming \ typora user images \ image-20210914102234966. PNG)]

storeFile=../keystore/jiuan.jks
storePassword=******
keyAlias=******
keyPassword=******
2.3 in the build.gradle file, import the properties file information
/**
 * Create a file key.properties under the project root path
 */
def keystorePropertiesFile = rootProject.file('key.properties')
//Create a properties object
def keystoreProperties = new Properties()
//Load the contents in key.properties
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
2.4 in the build.gradle file, add the signature configuration in the android - "signingConfigs" tag
 //Signature configuration
signingConfigs {
	config {
		storeFile file(keystoreProperties['storeFile']) //Signature file
		storePassword keystoreProperties['storePassword']  //Signature file password
		keyAlias keystoreProperties['keyAlias']       //Signature file alias
		keyPassword keystoreProperties['keyPassword']     //Alias password
	}
}
2.5 in the build.gradle file, use the signature configuration in the android - "buildTypes" tag (the same set of signatures can be used for debug and release versions)
//Build type
buildTypes {
    debug {
        //Web address switching during script construction
        buildConfigField('String', 'BASE_URL', '"https://qingchenglive.com"')
        zipAlignEnabled true //Zialign optimization
        shrinkResources false // Remove useless resource files
        minifyEnabled false //Open obfuscation
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        signingConfig signingConfigs.config//The signature method is called here
    }
    release {
        //Web address switching during script construction
        buildConfigField('String', 'BASE_URL', '"https://qingchenglive.com"')
        zipAlignEnabled true //Zialign optimization
        shrinkResources false // Remove useless resource files
        minifyEnabled false //Open obfuscation
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        signingConfig signingConfigs.config//The signature method is called here
    }
}

3. Configure multi-channel

3.1 in the build.gradle file, add channels under the android - "productFlavors" tab
/**
* Multi channel configuration
*/
productFlavors {
    ja_update {}
    ja_oppo {}
    ja_vivo {}
    ja_xiaomi {}
    ja_huawei {}
    ja_yingyongbao {}
    ja_pp {}
}
3.2 after Android studio 3.0, flavor dimensions are added to define flavor dimensions

Flavordimens are defined under the android - defaultConfig tag. You can define multiple, separated by commas

defaultConfig {
    //Flavor dimension - increase the configurability of multi-channel packaging, and the same channel can be subdivided
    flavorDimensions "frame_flavor"
}

Each channel must define its own flavor

/**
* Multi channel configuration
*/
productFlavors {
    ja_update {
        dimension "frame_flavor"
    }
    ja_oppo {
        dimension "frame_flavor"
    }
    ja_vivo {
        dimension "frame_flavor"
    }
    ja_xiaomi {
        dimension "frame_flavor"
    }
    ja_huawei {
        dimension "frame_flavor"
    }
    ja_yingyongbao {
        dimension "frame_flavor"
    }
    ja_pp {
        dimension "frame_flavor"
    }
}
3.3 placeholders in the configuration manifest file

Use ${key} to define placeholders in the manifest file - different channels use different application names:

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="${app_name}"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/Theme.Frame">

In the build.gradle file, android - "productFlavors"

/**
* Multi channel configuration
*/
productFlavors {
    ja_update {
        dimension "frame_flavor"
        //The key remains the same as the placeholder in the manifest file and can be replaced
        manifestPlaceholders = ["app_name": "Picture editing map bottom changing"]
    }
    ...
}
3.4 traverse multiple channels and add common configuration

android - under the productFlavors tab

productFlavors.all {
    flavor ->
        //applicationId must be specified, otherwise it cannot be compiled
        flavor.applicationId = "com.jiuan.frame"
        flavor.dimension = "frame_flavor"
        flavor.signingConfig = signingConfigs.config
        flavor.manifestPlaceholders.put("channel", name)//Set channel number
        flavor.manifestPlaceholders.put("application_id", flavor.applicationId)//Replace the placeholder application in the manifest_ id
        if (flavor.manifestPlaceholders.get("app_name") == null) {
            //If the upper channel does not specify an app_name, then use the default application name to replace the placeholder app in the manifest_ name
            flavor.manifestPlaceholders.put("app_name", getDefaultAppName())
        }
}

getDefaultAppName() gets the default application name and defines the method outside the android tag

def getDefaultAppName() {
    return "Add a picture frame"
}
3.5 obtaining current channels in the application

Add meta data tag in manifest file to configure channel placeholder (under application tag)

<meta-data
   android:name="channel"
   android:value="${channel}" />

In the build.gradle file, android - "productFlavors", set the channel placeholder

/**
* Multi channel configuration
*/
productFlavors {
    ja_update {
        dimension "frame_flavor"
        //The key remains the same as the placeholder in the manifest file and can be replaced
        manifestPlaceholders = ["channel": "Picture editing map bottom changing"]
    }
    ...
}

Get channel number from application

private String getChannel() {
    try {
        PackageManager pm = getPackageManager();
        ApplicationInfo appInfo = pm.getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA);
        String channel = appInfo.metaData.getString("channel"); // key is the name in the < meta data > tag
        if (!TextUtils.isEmpty(channel)) {
            return channel;
        }
    } catch (Exception e){
        e.printStackTrace();
    }
    return null;
}
3.6 user defined output path (when packaging, packages from multiple channels can be generated in the same folder)

android - under the productFlavors tab

applicationVariants.all { variant ->
    /**
     * debug Do not specify the output path for the version, otherwise you cannot install and debug
     * There is a problem after setting the output path -- gradle 6.7
     */
    if ("release".equals(variant.buildType.name)) {
        variant.packageApplicationProvider.get().outputDirectory = rootProject.file("/apks/${variant.versionName}")
    }
    //Build type
    def buildType = variant.buildType.name
    //Named after Android studio 3.0
    variant.outputs.all {
        //File name splicing
        outputFileName = "imageeditor_${variant.flavorName}_v${defaultConfig.versionName}_${releaseTime()}_${buildType}.apk"
    }
}

releaseTime() formats the current time and defines the method outside the android tag

//Release time
def releaseTime() {
    //When setting the release time, do not set the hours. In this case, the packages generated every hour are different. During installation, studio will report an exception that apk cannot be found
//    return new Date().format('MMddHH', TimeZone.getTimeZone('GMT+8'))
    return new Date().format('MMdd', TimeZone.getTimeZone('GMT+8'))
}

4 extraction tools

4.1 under the current module directory (the same level as the build.gradle file), create a configuration file config.gradle to integrate the above functions
/**
 * Create a file key.properties under the project root path
 */
def keystorePropertiesFile = rootProject.file('key.properties')
//Create a properties object
def keystoreProperties = new Properties()
//Load the contents in key.properties
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))

android {

    defaultConfig {
        //Flavor dimension - increase the configurability of multi-channel packaging, and the same channel can be subdivided
        flavorDimensions "frame_flavor"
    }

    //Signature configuration
    signingConfigs {

        config {
            storeFile file(keystoreProperties['storeFile']) //Signature file
            storePassword keystoreProperties['storePassword']  //Signature file password
            keyAlias keystoreProperties['keyAlias']       //Signature file alias
            keyPassword keystoreProperties['keyPassword']     //Alias password
        }

    }

    //Build type
    buildTypes {

        debug {
            //Web address switching during script construction
            buildConfigField('String', 'BASE_URL', '"https://qingchenglive.com"')

            zipAlignEnabled true //Zialign optimization
            shrinkResources false // Remove useless resource files
            minifyEnabled false //Open obfuscation
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.config//The signature method is called here
        }

        release {
            //Web address switching during script construction
            buildConfigField('String', 'BASE_URL', '"https://qingchenglive.com"')

            zipAlignEnabled true //Zialign optimization
            shrinkResources false // Remove useless resource files
            minifyEnabled false //Open obfuscation
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.config//The signature method is called here
        }

    }

    /**
     * Multi channel configuration
     */
    productFlavors {
        ja_update {

        }
        ja_oppo {
            //Replace placeholder app in manifest_ name
            manifestPlaceholders = ["APP_NAME": "Picture editing map bottom changing"]
        }
        ja_vivo {
            manifestPlaceholders = ["APP_NAME":"Picture editing PS"]
        }
        ja_xiaomi {
            manifestPlaceholders = ["APP_NAME":"Picture editing map bottom changing"]
        }
        ja_huawei {
            manifestPlaceholders = ["APP_NAME":"Add a picture frame"]
        }
        ja_yingyongbao {
            manifestPlaceholders = ["APP_NAME":"Interesting picture editing"]
        }
        ja_pp {
            manifestPlaceholders = ["APP_NAME":"Picture editing map bottom changing"]
        }

        productFlavors.all {
            flavor ->
                //applicationId must be specified, otherwise it cannot be compiled
                flavor.applicationId = "com.jiuan.frame"
                flavor.dimension = "frame_flavor"
                flavor.signingConfig = signingConfigs.config
                flavor.manifestPlaceholders.put("channel", name)//Set channel number
                flavor.manifestPlaceholders.put("application_id", flavor.applicationId)//Replace the placeholder application in the manifest_ id
                if (flavor.manifestPlaceholders.get("app_name") == null) {
                    //If the upper channel does not specify an app_name, then use the default application name to replace the placeholder app in the manifest_ name
                    flavor.manifestPlaceholders.put("app_name", getDefaultAppName())
                }

        }

        applicationVariants.all { variant ->
            /**
             * debug Do not specify the output path for the version, otherwise you cannot install and debug
             * There is a problem after setting the output path -- gradle 6.7
             */
            if ("release".equals(variant.buildType.name)) {
                variant.packageApplicationProvider.get().outputDirectory = rootProject.file("/apks/${variant.versionName}")
            }
            //Build type
            def buildType = variant.buildType.name
            //Named after Android studio 3.0
            variant.outputs.all {
                //File name splicing
                outputFileName = "imageeditor_${variant.flavorName}_v${defaultConfig.versionName}_${releaseTime()}_${buildType}.apk"
            }
        }

    }

}

//Release time
def releaseTime() {
    //When setting the release time, do not set the hours. In this case, the packages generated every hour are different. During installation, studio will report an exception that apk cannot be found
//    return new Date().format('MMddHH', TimeZone.getTimeZone('GMT+8'))
    return new Date().format('MMdd', TimeZone.getTimeZone('GMT+8'))
}

def getDefaultAppName() {
    return "Add a picture frame"
}
4.2 import in build.gradle file
plugins {
    id 'com.android.application'
    id 'kotlin-android'
}

//Introduction configuration
apply from :'config.gradle'

android {
	...
}

Keywords: Android Gradle

Added by duelist on Fri, 19 Nov 2021 07:15:17 +0200