1. 基本概念
- 项目级
build.gradle
主要用于配置整个项目的构建设置 - 模块级
build.gradle
配置各个module的构建设置,指定了项目编译版本、打包配置及依赖库等
2. 项目级 build.gradle
2.1 文件内容
gradle
复制代码
// Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { repositories { mavenLocal() google() jcenter() maven { allowInsecureProtocol = true url "http://mvnrepo.alibaba-inc.com/mvn/repository" } } dependencies { classpath 'com.android.tools.build:gradle:3.5.1' } } allprojects { repositories { mavenLocal() google() jcenter() maven { allowInsecureProtocol = true url "http://mvnrepo.alibaba-inc.com/mvn/repository" } } } task clean(type: Delete) { delete rootProject.buildDir }
buildscript
- gradle脚本执行所需依赖。repositories
- 配置依赖库仓库dependencies
- 依赖插件
allprojects
- 各个module gradle脚本执行所需依赖。repositories
- 配置依赖库仓库
task clean
- 执行clean时,会删除build目录篇幅限制下面就只能给大家展示小册部分内容了。这份面试笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题
需要全套面试笔记【点击此处】即可免费获取
3. 模块级 build.gradle
3.1 文件内容
gradle
复制代码
apply plugin: 'com.android.application' android { compileSdkVersion 30 defaultConfig { minSdkVersion 21 targetSdkVersion 30 versionCode 1 versionName "1.0" applicationId 'com.xxx.xxx' buildConfigField "boolean", "NeedLogger", 'true' buildConfigField "String", "AUTH_SECRET", '"请填入您的密钥"' } sourceSets { main { java.srcDirs = ['src/main/java'] jniLibs.srcDirs = ['libs'] res.srcDirs = ['src/main/res'] } } signingConfigs { debug { keyAlias 'xx' keyPassword 'xx' storeFile file('xx/xx.keystore') storePassword 'xx' v1SigningEnabled true v2SigningEnabled true } release { keyAlias 'xx' keyPassword 'xx' storeFile file('xx/xx.keystore') storePassword 'xx' v1SigningEnabled true v2SigningEnabled true } } buildTypes { release { debuggable false minifyEnabled true proguardFile file('proguard-rules.pro') zipAlignEnabled false multiDexEnabled true signingConfig signingConfigs.release } debug { debuggable true minifyEnabled false zipAlignEnabled false multiDexEnabled true signingConfig signingConfigs.debug } } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar','*.aar']) implementation 'androidx.appcompat:appcompat:1.3.1' implementation 'com.android.support.constraint:constraint-layout:1.0.2' }
apply plugin
- 应用插件android
- 配置项目构建的各种属性dependencies
- 依赖库
3.2 apply plugin
插件
apply plugin: 'com.android.application'
是项目级build.gradle
里面引入的插件classpath 'com.android.tools.build:gradle:3.5.1'
com.android.application
表示该module是一个APP项目,编译产物是apkcom.android.library
表示该module是一个库,编译产物是aar
引入其他插件
gradle
复制代码
//项目级build.gradle dependencies { classpath 'com.android.tools.build:gradle:3.5.1' // 引入kotlin插件依赖 classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.20' } //模块级build.gradle apply plugin: 'com.android.application' // 引入kotlin插件 apply plugin:'kotlin-android'
3.3 android
项目配置
compileSdkVersion 30
- 编译版本,配置当前项目使用API 30的android.jar参与编译,可以在项目目录-External Libraries-<Android API 30> 找到 android.jarbuildToolsVersion '30.0.3'
defaultConfig
- 项目信息默认配置,优先级最低minSdkVersion 21
- 最低支持的版本设备targetSdkVersion 30
- 目标适配的版本,比如设置成23以下,就不需要动态申请权限versionCode 1
- 版本号,用于对比两个APP的版本大小,判断是否可以覆盖安装versionName "1.0"
- 显示版本号,作为展示使用applicationId 'com.xxx.xxx'
- 包名buildConfigField "boolean", "NeedLogger", 'true'
- 在BuildConfig.class内生成一个boolean NeedLogger = true的变量buildConfigField "String", "AUTH_SECRET", '"请填入您的密钥"'
- 在BuildConfig.java内生成一个String Auth_SECRET = "请填入您的密钥",注意要加引号,否则编译错误
sourceSets
- 指定代码,配置等的目录,可以配置不同的渠道的配置目录signingConfigs
- 配置签名相关dependencies
- 依赖库配置
3.3.1 多渠道打包
gradle
复制代码
android { // ... // 定义构建变体的维度,例如这里定义了"market" 和 "tier" 两个维度 flavorDimensions "market", "tier" // 根据 flavorDimensions 定义不同的产品风味,如 free 和 pro productFlavors { xiaomi { dimension "market" } huawei { dimension "market" } free { dimension "tier" applicationIdSuffix ".free" versionNameSuffix "-free" } pro { dimension "tier" applicationIdSuffix ".pro" versionNameSuffix "-pro" } } }
此时会构建market(2) * tier(2) * buildTypes(2) = 8个渠道的包
看下编译生成的BuildConfig.java,可以通过匹配渠道做不同的操作,比如初始化不一样的推送(小米或华为),显示收费或者免费等等
java
复制代码
public final class BuildConfig { public static final boolean DEBUG = Boolean.parseBoolean("true"); public static final String APPLICATION_ID = "com.xx"; public static final String BUILD_TYPE = "debug"; public static final String FLAVOR = "huaweiFree"; public static final int VERSION_CODE = 1; public static final String VERSION_NAME = "1.0-free"; public static final String FLAVOR_market = "huawei"; public static final String FLAVOR_tier = "free"; // Fields from default config. public static final String AUTH_SECRET = "请填入您的密钥"; public static final boolean NeedLogger = true; }
3.3.2 动态配置
- 动态配置BuildConfig代码
gradle
复制代码
buildTypes { release { // ... buildConfigField "boolean", "NeedLogger", 'false' } debug { // ... buildConfigField "boolean", "NeedLogger", 'true' } } // code,测试包自动打开日志,正式包关闭日志输出 if (BuildConfig.NeedLogger) { Log.i(TAG, "xxxx"); }
- 动态配置AndroidManifest.xml
xml
复制代码
// AndroidManifest.xml <data android:scheme:"${xx_scheme}"/> // build.gradle buildTypes { release { // ... manifestPlaceholders = [xx_scheme: "release_scheme"] } debug { // ... manifestPlaceholders = [xx_scheme: "debug_scheme"] } }
- 动态配置资源
渠道和buildType可以分别配置不同的资源,例如huaweiFreeDebug
按照默认约定,可以创建如下目录
xml
复制代码
// debug/strings.xml <string name="test_value">debug</string> // free/strings.xml <string name="test_value">free</string> // huawei/strings.xml <string name="test_value">huawei</string> // main/strings.xml <string name="test_value">main</string>
huaweiFreeDebug
内部资源优先级debug
>huawei
>free
>main
一般正式url可以配置在main/strings.xml
,测试url可以配置在debug/strings.xml
,这样在打包的时候就可以自动选择不同环境url,不需要手动去修改代码或配置切换。
另外,也可以手动配置资源路径,例如在项目根目录创建common/main,sourceSets可以配置此目录
gradle
复制代码
sourceSets { main { // ... res.srcDirs += ["${rootProject.projectDir}/common/main/java"] res.srcDirs += ["${rootProject.projectDir}/common/main/res"] } huawei { } xiaomi { } }
3.4 dependencies
项目依赖
指定当前项目依赖的第三方库,常用的方式有四种
implementation
- 该依赖方式的三方库,项目可以直接调用三方库里面的代码或其他资源。并且可以依赖传递,会将该三方库依赖的其他的库一起引入,默认使用版本最高的那个。api
- 当前module如果是library,该依赖方式引入的三方库,会将三方库的代码、配置等一起打入当前module中。如果当前module是application,和implementation无区别compileOnly
- 只在编译期使用,最终产物不会包含该依赖库的代码,一般搭配编译插件使用runtimeOnly
- 只在运行时使用,编码期间无法使用该依赖库内的代码或者其他资源,最终产物会包含该依赖库的所有代码和资源。
php
复制代码
// 常用依赖 implementation 'androidx.appcompat:appcompat:1.2.0' // 统一定义版本号 appcompatVersion = '1.2.0' implementation "androidx.appcompat:appcompat:$appcompatVersion" // 依赖module implementation project(path: ':moduleA')
结合多渠道打包的变体
可以根据Debug或Release包引入不同依赖。比如工具库LeakCanary,用于检测内存泄漏,仅希望在测试包中使用,在正式包中剔除该功能。可以使用如下方式依赖
gradle
复制代码
debugImplementation "com.xxx.xxx:LeakCanary:1.0.0" releaseImplementation "com.xxx.xxx:LeakCanary-no-op:1.0.0"
还可以根据不同渠道引入不同依赖sdk。比如小米渠道引入小米推送sdk,华为推送引入华为sdk
gradle
复制代码
xiaomiImplementation 'xiaomipushsdk' huaweiImplementation 'huaweipushsdk'
AndroidStudio提示了很多种,可以自行选择
剔除冲突的依赖
有一种场景,maven依赖和aar依赖同时包含了同一个库,编译时就会冲突,处理方式有两种
- 通过exclude方式排除掉,优点是简单,缺点是每个冲突的依赖库都得加
gradle
复制代码
implementation('com.xxx.xxx:xxx:1.0.0') { exclude group:'com.xxx', module:'xx' }
- 让aar提供方去掉冲突的库