What have you learned after reading this article?

  • Familiar with gradle build configuration
  • Familiarize yourself with the directory structure of your code build environment; you know more than just SRC /main
  • Development, build, and so on can be packaged arbitrarily
  • Multi-channel packaging
  • APK output file configuration

demand

We usually have debug and release environments for development, but what if you want to separate beta 1, beta 2, and so on?

This relies on the power of Gradle for configuration.

You can also refer to Google’s official documentation for configuration.

Configuring build TypesbuildTypes

* We usually package for different build environments, such as debug, release, beta, etc., which we call buildTypes.

You can create and configure build types inside the Android {} code block in the module-level build.gradle file. When you create a new module, Android Studio automatically creates the debug and publish build types for you. Although the debug build type does not appear in the build profile, Android Studio configures it to Debuggable True. This way, you can debug your application on a secure Android device and configure APK signing using a common debug keystore.

If you want to add or change specific Settings, you can add debug build types to your configuration. The following example specifies applicationIdSuffix for the debug build type and configures a JNidebug build type initialized with the Settings in the debug build type.

ApplicationIdSuffix: Field indicates that you suffix your default program ID (package name) without changing it. For example, if your package name is com.rae.app, and you want to distinguish between test packages and formal packages, set applicationIdSuffix to.debug, and your app’s package name becomes com.rae.app.debug

android { ... defaultConfig {... } buildTypes { release { minifyEnabledtrue
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }

        debug {
            applicationIdSuffix ".debug"
        }

        /** * The 'initWith' property allows you to copy configurations from other build types, * so you don't have to configure one from the beginning. You can then configure * just the settings you want to change. The following line initializes * 'jnidebug' using the debug build type, and changes only the * applicationIdSuffix and versionNameSuffix settings. */

        jnidebug {

            // This copies the debuggable attribute and debug signing configurations.
            initWith debug

            applicationIdSuffix ".jnidebug"
            jniDebuggable true}}}Copy the code

Build the source set

Noun resolution: The source code is usually stored in the SRC /main folder, but you want to be able to differentiate the source files based on the build type (e.g. debug, release), so that the corresponding folder is a different build source. For example, debug is built from SRC/DEBUG, release is built from SRC /release, and SRC /main is defined as a common resource, which is merged at build time.

See the official documentation for more information.

Android Studio logically groups the source code and resources for each module into a set of sources. The main/ source set of a module contains the code and resources shared by all of its build variants. Other source set directories are optional, and Android Studio does not automatically create these directories for you when you configure new build variants. However, creating a source set like main/ helps keep the files and resources that Gradle should only use when building a particular version of the application in order:

Build sources are named as follows:

ProductFlavor represents the channel package, as shown in the multichannel package below

  • SRC /main/ This source set contains code and resources shared by all build variants.

  • SRC /

    / create this source set to add code and resources specific to a particular buildType. Example: the SRC/jnidebug

  • SRC / / create this source set to add code and resources specific to a specific productFlavor. For example baidu channel package: SRC /baidu

  • SRC / / Create this source set to add code and resources specific to a particular build variant.

For example, to generate a “fully debugged” version of an application, the build system incorporates code, Settings, and resources from the following set of sources. For example, Baidu’s development environment package is SRC /baiduDebug

Build type dependency configuration

Most of the time, we will separate the SDK or API interface into a library, which is usually divided into production environment and test environment, but when we rely on it, we will refer to it like this: Compile project(‘: SDK ‘), such that the dependent environment is release, not when testing the environment during debugging. We’ll have to do it another way:

<buildType>Compile project()

This will depend on different packages for different build types, such as our test environment dependencies :debugCompile Project (‘: SDK ‘), and jnidebug: jnidebugCompile Project (‘: SDK ‘).

How does my current build type correspond to other modules? For example, if your app depends on the DEBUG environment of the SDK Module, you can do this:

Configuration:

of the target module, such as the debug buildType of

in your SDK

debugCompile project(path: ':sdk', configuration: 'debug')

Composite sample

Build. Gradle configuration:

apply plugin: 'com.android.application'

android {
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        debug {
            applicationIdSuffix '.debug'
            minifyEnabled false
        }
        
        // A custom build type. The name should be arbitrary and make sense
        raedebug {
            initWith debug
            applicationIdSuffix '.raedebug'
        }
    }
}

dependencies {
    // Generate environment dependencies
    releaseCompile project(path: ':sdk', configuration: 'release')
    // Test environment dependencies
    debugCompile project(path: ':sdk', configuration: 'debug')
    // Customize build type dependencies
    raedebugCompile project(path: ':sdk', configuration: 'uutest')
}

Copy the code

Build. Gradle configuration for SDK Module:

apply plugin: 'com.android.library'

android {
       buildTypes {
        debug {
            debuggable true
            minifyEnabled false
        }
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        
        // The configuration of raedebugCompile project must be matched.
        uutest {
            initWith debug
        }
    }
}

Copy the code

Multi-channel packagingproductFlavors

Take a look at the build.gradle configuration first

android{

    // Channel package definition. The default definition name is the channel name
    productFlavors {
 
        dev {} / / test
        baidu {}        // Baidu Mobile Assistant
        yinyongbao {}   / / application
        m360 {}         // 360 mobile Assistant
        pp {}           / / PP assistant
        anzhi{}         // Anzhi Market
        xiaomi {}       // The xiaomi store
        letv {}         // LeEco Store
        huawei {}       // Huawei Store
        lenovomm {}     // Lenovo Music Store
        other {}        // Other markets
        official{}      // Official version
 
    }
 
    // Batch channel package value replacement
    productFlavors.all { flavor ->
        // UMENG_CHANNEL is configured according to your androidmanifest.xml, see below.
        flavor.manifestPlaceholders = [UMENG_CHANNEL: name, JPUSH_CHANNEL: name]
    }
}
Copy the code

Androidmanifest.xml configuration:


<?xml version="1.0" encoding="utf-8"? >
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.rae.demo">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
       
       <! Use ${variable name} to replace variables, not only with <meta-data /> tags, but with anything you want. -->
         <meta-data
            android:name="UMENG_APPKEY"
            android:value="${UMENG_APPKEY}"/>
        
        <meta-data
            android:name="UMENG_CHANNEL"
            android:value="${UMENG_CHANNEL}"/>
        
        <! --${variable with transform}-->   
        <activity
            android:name=".DemoActivity"
            android:label=${variable with transformation}/>
            
    </application>

</manifest>
Copy the code

After Sync Gradle, look at the Gradle Projects pane and you will find out what to do with the various Build types you will find in the Build Variants pane.

APK output configuration

After combining with multi-channel packaging, the operation side hopes that the channel package we give is in this format app-{version number}-{channel name}. Apk, then let’s see how to meet the multi-channel packaging output APK file name modification.

android{

    // Output file configuration
   applicationVariants.all { variant ->
        variant.outputs.each { output ->
            def outputFile = output.outputFile
            if (outputFile ! =null && outputFile.name.endsWith('.apk')) {
                def dirName = outputFile.parent // Outputs the location of the folder
            
                // Change the file name
                def fileName = "app-${output.processResources.variantName}-${defaultConfig.versionName}-${variant.flavorName}.apk"
                
                // If you don't want to bother, just add the version number:
                // def fileName = outputFile.name.replace(".apk", "-${defaultConfig.versionName}.apk")
                
                
                output.outputFile = new File(dirName, fileName)
            }
        }
    }
}
Copy the code

The multi-channel packaging described above uses the default gralde configuration, but the downside is that each channel package is recompiled once, which is slow. For a large number of multi-channel packaging recommended using Meituan Walle, project address: github.com/Meituan-Dia…