Android build.gradle configuration details

Android Studio uses gradle to build projects, and gradle is based on the groovy language. If you just use it to build ordinary Android projects, you don't need to learn groovy. When we create an Android project, it will contain two Android build.gradle configuration detailed files, as shown below:
build.gradle location.png

1. Project build.gradle file:

The corresponding build.gradle code is as follows:

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {//这里是gradle脚本执行所需依赖,分别是对应的maven库和插件
    
    repositories {
        google()//从Android Studio3.0后新增了google()配置,可以引用google上的开源项目
        jcenter()//是一个类似于github的代码托管仓库,声明了jcenter()配置,可以轻松引用 jcenter上的开源项目
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.0.0'此处是android的插件gradle,gradle是一个强大的项目构建工具
        

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {//这里是项目本身需要的依赖,比如项目所需的maven库
    repositories {
        google()
        jcenter()
    }
}

// 运行gradle clean时,执行此处定义的task任务。
// 该任务继承自Delete,删除根目录中的build目录。
// 相当于执行Delete.delete(rootProject.buildDir)。
// gradle使用groovy语言,调用method时可以不用加()。
task clean(type: Delete) {
    delete rootProject.buildDir
}
  • The buildscript{} closure is the dependencies required for the execution of the gradle script, which are the corresponding maven libraries and plug-ins.
  • The allprojects{} closure is the dependencies required by the project itself, such as the maven library required by the project.
  • task clean(type: Delete){} is to execute the task task defined here when running gradle clean. This task inherits from Delete and deletes the build directory in the root directory. The buildscript contains repositories closure and dependencies closure.

repositories{} closure: configure remote warehouse

The closure declares the configuration of jcenter() and google(), where jcenter is a code hosting warehouse that hosts many Android open source projects. After configuring jcenter here, we can easily refer to the open source projects on jcenter in the project , the google() configuration has been added since Android Studio 3.0, which can refer to open source projects on google.

dependencies{} closure: configure build tools

The closure declares a Gradle plug-in using classpath. Since Gradle is not only used to build Android projects, related plug-ins are introduced here to build Android projects, where '3.0.0' is the version number of the plug-in, which can be based on the latest version number to adjust.

2. Module's build.gradle file:

It can be seen from the content of the file that it is mainly divided into three parts, as shown in the following figure:
Module的build.gradle.png

1、apply plugin:

// 声明是Android程序,
//com.android.application 表示这是一个应用程序模块
//com.android.library 标识这是一个库模块
//而这区别:前者可以直接运行,后着是依附别的应用程序运行
apply plugin: 'com.android.application'

The first line in the file uses apply plugin to indicate that a plugin is applied, and the plugin generally has two optional values:

  • 'com.android.application' means that the module is an application module, which can be run directly, and the packaged one is an .apk file
  • 'com.android.library' means that the module is a library module, which can only be run as a code library attached to other application modules, and the packaged one is an .aar file

2. android{} closure:

This closure is mainly to configure various properties of project construction:
#####2.1, add signingConfigs{} closure:

    signingConfigs {// 自动化打包配置
        release {// 线上环境
            keyAlias 'test'
            keyPassword '123456'
            storeFile file('test.keystore')
            storePassword '123456'
        }
        debug {// 开发环境
            keyAlias 'test'
            keyPassword '123456'
            storeFile file('test.keystore')
            storePassword '123456'
        }
    }

You can manually add the signature configuration, or select the app through Project Structure, and click Singing to add. The specific steps are shown in the figure below:
Configure Singing.png
After the signature configuration is completed, it can be conveniently packaged with the signature. There are two Types in the Build Variants of the module, which are debug and release, you can choose any type for packaging, and they will use their configured Keys for packaging. Executing Run app or Build->Build apk will automatically generate an Apk file under the module name/app/build/outputs/apk path. Another packaging method is Build->Generate Signed APK to fill in the signature information to generate Apk.

2.2, compileSdkVersion: Set the Android version used when compiling

2.3, buildToolsVersion: Set the version of the build tool used when compiling, and remove this configuration after Android Studio 3.0

2.4, defaultConfig{} closure:
    compileSdkVersion 27//设置编译时用的Android版本
    defaultConfig {
        applicationId "com.billy.myapplication"//项目的包名
        minSdkVersion 16//项目最低兼容的版本
        targetSdkVersion 27//项目的目标版本
        versionCode 1//版本号
        versionName "1.0"//版本名称
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"//表明要使用AndroidJUnitRunner进行单元测试
    }
  • applicationId : specifies the package name of the project.
  • minSdkVersion : Specifies the minimum compatible version of the project. If the device is smaller than this version or larger than maxSdkVersion (generally not used), this application cannot be installed. Here, it is specified as 16, which means that it is at least compatible with the Android 4.1 system.
  • targetSdkVersion : Specify the target version of the project, indicating that the target version has been fully tested, the system will start some of the latest features corresponding to the target system for the application, and the behavior of the Android system platform changes, only the attribute value of targetSdkVersion is set It will take effect only when it is greater than or equal to the API version of the system platform. For example, if you specify a targetSdkVersion value of 22, it means that the program has only been fully tested on the Android 5.1 version at most. On the Android 6.0 system (corresponding to a targetSdkVersion of 23), new features such as system runtime permissions and other functions will be available. will not be enabled.
  • versionCode : Indicates the version number. Generally, this value can only increase each time it is packaged and launched, and it cannot be seen after packaging.
  • versionName : Indicates the version name, displayed in the application market.
  • testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" indicates that AndroidJUnitRunner is to be used for unit testing.
2.5, buildTypes{} closure:

This closure mainly specifies the main configuration for generating the installation file, and generally includes two sub-closures, one is the debug closure, which is used to specify the configuration for generating the test version installation file, which can be ignored; the other is the release closure, which is used for Specifies the configuration for generating production installation files. The parameters that can be configured by the two are the same, and the biggest difference is that the default attribute configuration is different. The attribute configuration supported by the two modes is as follows:
buildTypes configuration.png

    buildTypes {// 生产/测试环境配置
        release {// 生产环境
            buildConfigField("boolean", "LOG_DEBUG", "false")//配置Log日志
            buildConfigField("String", "URL_PERFIX", "\"https://release.cn/\"")// 配置URL前缀
            minifyEnabled false//是否对代码进行混淆
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'//指定混淆的规则文件
            signingConfig signingConfigs.release//设置签名信息
            pseudoLocalesEnabled false//是否在APK中生成伪语言环境,帮助国际化的东西,一般使用的不多
            zipAlignEnabled true//是否对APK包执行ZIP对齐优化,减小zip体积,增加运行效率
            applicationIdSuffix 'test'//在applicationId 中添加了一个后缀,一般使用的不多
            versionNameSuffix 'test'//在applicationId 中添加了一个后缀,一般使用的不多
        }
        debug {// 测试环境
            buildConfigField("boolean", "LOG_DEBUG", "true")//配置Log日志
            buildConfigField("String", "URL_PERFIX", "\"https://test.com/\"")// 配置URL前缀
            minifyEnabled false//是否对代码进行混淆
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'//指定混淆的规则文件
            signingConfig signingConfigs.debug//设置签名信息
            debuggable false//是否支持断点调试
            jniDebuggable false//是否可以调试NDK代码
            renderscriptDebuggable false//是否开启渲染脚本就是一些c写的渲染方法
            zipAlignEnabled true//是否对APK包执行ZIP对齐优化,减小zip体积,增加运行效率
            pseudoLocalesEnabled false//是否在APK中生成伪语言环境,帮助国际化的东西,一般使用的不多
            applicationIdSuffix 'test'//在applicationId 中添加了一个后缀,一般使用的不多
            versionNameSuffix 'test'//在applicationId 中添加了一个后缀,一般使用的不多
        }
    }
The release{} closure and the debug{} closure can configure the same parameters. The biggest difference is that the default attribute configuration is different:
  • minifyEnabled : indicates whether to confuse the code, true means to confuse the code, false means not to confuse the code, the default is false.
  • proguardFiles : Specifies the obfuscated rule file. Here, two files, proguard-android.txt and proguard-rules.pro, are specified. The proguard-android.txt file is the default obfuscation file, which defines some general obfuscation rules. The proguard-rules.pro file is located in the root directory of the current project, and some project-specific obfuscation rules can be defined in this file.
  • buildConfigField : It is used to solve the difference between the Beta version service and the Release version service address or some Log printing requirements control. For example: configure buildConfigField("boolean", "LOG_DEBUG", "true"), this method receives three non-empty parameters, the first: determine the type of the value, the second: specify the name of the key, and the third: Pass the value, BuildConfig.LOG_DEBUG can be called when calling.
  • debuggable : Indicates whether to support breakpoint debugging, release defaults to false, and debug defaults to true.
  • jniDebuggable : Indicates whether NDK code can be debugged, use lldb for c and c++ code debugging, release defaults to false
  • signingConfig : Set the signature information, configure the corresponding signature through signingConfigs.release or signingConfigs.debug, but before adding this configuration, you must first add the signingConfigs closure and add the corresponding signature information.
  • renderscriptDebuggable : Indicates whether to enable the rendering script, which is some rendering methods written in c, and the default is false.
  • renderscriptOptimLevel : Indicates the rendering level, the default is 3.
  • pseudoLocalesEnabled : Whether to generate a pseudo locale in the APK to help internationalization, generally not used much.
  • applicationIdSuffix : It is the same as the configuration in defaultConfig. Here, a suffix is ​​added to applicationId, which is generally not used much.
  • versionNameSuffix : Indicates adding the suffix of the version name, which is generally not used much.
  • zipAlignEnabled : Indicates whether to perform ZIP alignment optimization on the APK package to reduce the zip volume and increase operating efficiency. Both release and debug are true by default.
2.6, sourceSets{} closure: configuration directory pointing
    sourceSets {//目录指向配置
        main {
            jniLibs.srcDirs = ['libs']//指定lib库目录
        }
    }

Configure jniLibs.srcDirs = ['libs'], the jniLibs folder can be generated in the Android view of Android studio, which can facilitate us to store jar packages and library files, where jniLibs in the Android view and libs in the project view point to the same folder (app→libs), as shown in the figure below:jniLibs.png

2.7, packagingOptions{} closure: related configuration when packaging

When more and more third-party libraries are relied on in the project, it is possible that the same (name) file exists in two dependent libraries. If so, Gradle will prompt an error (warning) when packaging. Then you can follow the prompts and use the following methods to remove duplicate files. The more common method is to remove duplicate files through exclude, for example:

    packagingOptions{
        //pickFirsts做用是 当有重复文件时 打包会报错 这样配置会使用第一个匹配的文件打包进入apk
        // 表示当apk中有重复的META-INF目录下有重复的LICENSE文件时  只用第一个 这样打包就不会报错
        pickFirsts = ['META-INF/LICENSE']

        //merges何必 当出现重复文件时 合并重复的文件 然后打包入apk
        //这个是有默认值得 merges = [] 这样会把默默认值去掉  所以我们用下面这种方式 在默认值后添加
        merge 'META-INF/LICENSE'

        //这个是在同时使用butterknife、dagger2做的一个处理。同理,遇到类似的问题,只要根据gradle的提示,做类似处理即可。
        exclude 'META-INF/services/javax.annotation.processing.Processor'
    }
2.8. productFlavors{} closure: multiple channel configurations

This configuration is often used. Usually, when adapting to multiple channels, it is necessary to do some special processing for specific channels, such as setting different package names and application names. Scenario: When we use Youmeng statistics, we usually need to set a channel ID, then we can use productFlavors to generate a package corresponding to channel information, such as:

android {  
    productFlavors {
        wandoujia {
            //豌豆荚渠道包配置
            manifestPlaceholders = [UMENG_CHANNEL_VALUE: "wandoujia"]
            //manifestPlaceholders的使用在后续章节(AndroidManifest里的占位符)中介绍
        }
        xiaomi {
            manifestPlaceholders = [UMENG_CHANNEL_VALUE: "xiaomi"]
            applicationId "com.wiky.gradle.xiaomi" //配置包名

        }
        _360 {
            manifestPlaceholders = [UMENG_CHANNEL_VALUE: "_360"]
        }
        //...
    }  
}

Of course there is also a more concise way:

android {  
    productFlavors {
        wandoujia {}
        xiaomi {}
        _360 {}
       //...
    }  

    productFlavors.all { 
        //批量修改,类似一个循序遍历
        flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name] 
    }
}

After configuration, enter gradlew assembleRelease (windows) in the command line window (Terminal) to start packaging. The corresponding command in the Mac system should be ./gradlew assembleRelease. Of course, if you want the debug version of the package, just change assembleRelease in the command to assembleDebug. The final generated package is still in app/build/outputs/apk, the default naming format is app-wandoujia-release-unsigned.apk, and the corresponding channel can be selected in the Build Variants of the module.
Note: Android Studio 3.0 needs to add a sentence after the version name in the defaultConfig
{ targetSdkVersion: *** minSdkVersion: *** versionCode: *** versionName: *** //version name, which means flavor dimension Its dimension is the version number, so the dimensions are all unified flavorDimensions "versionCode" }






2.9, lintOptions{} closure: code scanning analysis

Lint is a code scanning analysis tool provided by Android Studio, which can help us discover code structure/quality problems and provide some solutions, and this process does not require us to write test cases by hand.

Each problem found by Lint has description information and a level (similar to the bugs found by testing), so we can easily locate the problem and solve it according to the severity.

    //程序在编译的时候会检查lint,有任何错误提示会停止build,我们可以关闭这个开关
    lintOptions {
        abortOnError false //即使报错也不会停止打包
        checkReleaseBuilds false  //打包release版本的时候进行检测
    }

3. dependencies{} closure:

The closure defines the dependencies of the project. There are three types of dependencies in general projects: local dependencies, library dependencies, and remote dependencies. Local dependencies can add dependencies to local jar packages or directories, library dependencies can add dependencies to library modules in the project, and remote dependencies can add dependencies to open source projects on the jcener library.从Android Studio3.0后compile引入库不在使用,而是通过api和implementation,api完全等同于以前的compile,用api引入的库整个项目都可以使用,用implementation引入的库只有对应的Module能使用,其他Module不能使用,由于之前的项目统一用compile依赖,导致的情况就是模块耦合性太高,不利于项目拆解,使用implementation之后虽然使用起来复杂了但是做到降低偶合兴提高安全性。

dependencies {//项目的依赖关系
    implementation fileTree(include: ['*.jar'], dir: 'libs')//本地jar包依赖
    implementation 'com.android.support:appcompat-v7:27.1.1'//远程依赖
    implementation 'com.android.support.constraint:constraint-layout:1.1.2'
    testImplementation 'junit:junit:4.12'//声明测试用例库
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
  • implementation fileTree(include: ['*.jar'], dir: 'libs'): implementation fileTree is a local dependency statement, which means that all files with the .jar suffix in the libs directory are added to the project's build path.
  • implementation 'com.android.support:appcompat-v7:27.1.1' : The implementation statement is a remote dependency declaration, and 'com.android.support:appcompat-v7:27.1.1' is a standard remote dependency library format, where com .android.support is the domain name part, used to distinguish libraries of different companies; appcompat-v7 is the component name, used to distinguish different libraries of the same company; 27.1.1 is the version number, used to distinguish different versions of the same library. After adding this statement, Gradle will first check whether the library has been cached locally when building the project. If there is no cache, it will automatically download it online, and automatically add it to the build path of the project after downloading.
  • testImplementation and androidTestImplementation : Indicates the statement test case library.

##Module The complete build.gradle configuration is as follows:

// 声明是Android程序,
//com.android.application 表示这是一个应用程序模块
//com.android.library 标识这是一个库模块
//而这区别:前者可以直接运行,后着是依附别的应用程序运行
apply plugin: 'com.android.application'

android {
    signingConfigs {// 自动化打包配置
        release {// 线上环境
            keyAlias 'test'
            keyPassword '123456'
            storeFile file('test.jks')
            storePassword '123456'
        }
        debug {// 开发环境
            keyAlias 'test'
            keyPassword '123456'
            storeFile file('test.jks')
            storePassword '123456'
        }
    }
    compileSdkVersion 27//设置编译时用的Android版本
    defaultConfig {
        applicationId "com.billy.myapplication"//项目的包名
        minSdkVersion 16//项目最低兼容的版本
        targetSdkVersion 27//项目的目标版本
        versionCode 1//版本号
        versionName "1.0"//版本名称
        flavorDimensions "versionCode"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"//表明要使用AndroidJUnitRunner进行单元测试
    }
    buildTypes {// 生产/测试环境配置
        release {// 生产环境
            buildConfigField("boolean", "LOG_DEBUG", "false")//配置Log日志
            buildConfigField("String", "URL_PERFIX", "\"https://release.cn/\"")// 配置URL前缀
            minifyEnabled false//是否对代码进行混淆
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'//指定混淆的规则文件
            signingConfig signingConfigs.release//设置签名信息
            pseudoLocalesEnabled false//是否在APK中生成伪语言环境,帮助国际化的东西,一般使用的不多
            zipAlignEnabled true//是否对APK包执行ZIP对齐优化,减小zip体积,增加运行效率
            applicationIdSuffix 'test'//在applicationId 中添加了一个后缀,一般使用的不多
            versionNameSuffix 'test'//在applicationId 中添加了一个后缀,一般使用的不多
        }
        debug {// 测试环境
            buildConfigField("boolean", "LOG_DEBUG", "true")//配置Log日志
            buildConfigField("String", "URL_PERFIX", "\"https://test.com/\"")// 配置URL前缀
            minifyEnabled false//是否对代码进行混淆
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'//指定混淆的规则文件
            signingConfig signingConfigs.debug//设置签名信息
            debuggable false//是否支持断点调试
            jniDebuggable false//是否可以调试NDK代码
            renderscriptDebuggable false//是否开启渲染脚本就是一些c写的渲染方法
            zipAlignEnabled true//是否对APK包执行ZIP对齐优化,减小zip体积,增加运行效率
            pseudoLocalesEnabled false//是否在APK中生成伪语言环境,帮助国际化的东西,一般使用的不多
            applicationIdSuffix 'test'//在applicationId 中添加了一个后缀,一般使用的不多
            versionNameSuffix 'test'//在applicationId 中添加了一个后缀,一般使用的不多
        }
    }

    sourceSets {//目录指向配置
        main {
            jniLibs.srcDirs = ['libs']//指定lib库目录
        }
    }

    packagingOptions{//打包时的相关配置
        //pickFirsts做用是 当有重复文件时 打包会报错 这样配置会使用第一个匹配的文件打包进入apk
        // 表示当apk中有重复的META-INF目录下有重复的LICENSE文件时  只用第一个 这样打包就不会报错
        pickFirsts = ['META-INF/LICENSE']

        //merges何必 当出现重复文件时 合并重复的文件 然后打包入apk
        //这个是有默认值得 merges = [] 这样会把默默认值去掉  所以我们用下面这种方式 在默认值后添加
        merge 'META-INF/LICENSE'

        //这个是在同时使用butterknife、dagger2做的一个处理。同理,遇到类似的问题,只要根据gradle的提示,做类似处理即可。
        exclude 'META-INF/services/javax.annotation.processing.Processor'
    }

    productFlavors {
        wandoujia {}
        xiaomi {}
        _360 {}
    }

    productFlavors.all {
            //批量修改,类似一个循序遍历
        flavor -> flavor.manifestPlaceholders = [IFLYTEK_CHANNEL: name]
    }

    //程序在编译的时候会检查lint,有任何错误提示会停止build,我们可以关闭这个开关
    lintOptions {
        abortOnError false
        //即使报错也不会停止打包
        checkReleaseBuilds false
        //打包release版本的时候进行检测
    }

}

dependencies {
    //项目的依赖关系
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    //本地jar包依赖
    implementation 'com.android.support:appcompat-v7:27.1.1'
    //远程依赖
    implementation 'com.android.support.constraint:constraint-layout:1.1.2'
    testImplementation 'junit:junit:4.12'
    //声明测试用例库
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

Guess you like

Origin blog.csdn.net/Billy_Zuo/article/details/130391350