创建一个Android Studio工程默认情况下有三个gradle文件:
1.setting.gradle
2.根目录下build.gradle
3.app module目录下build.gradle
之前我们分析gradle时序的时候说过setting.gradle文件对应Setting对象,负责添加给定的module去构建。新工程默认情况下只有include ':app'语句。include对应Setting.include方法参数为module名称。
根目录下build.gradle文件:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {//gradle脚本执行所需依赖,分别对应远程仓库与插件
repositories { //远程仓库的依赖
maven{//maven远程仓库
...
}
google()//从Android Studio3.0后新增了google()配置,可以引用google上的开源项目
jcenter()//jcenter托管仓库,可以引用上面的托管代码
}
dependencies {
//插件依赖
classpath 'com.android.tools.build:gradle:3.4.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
//所有module的依赖
allprojects {
//远程仓库的依赖
repositories {
google()
jcenter()
}
}
//clean task 任务栈
//继承Delete类,删除根目录下build路径
task clean(type: Delete) {
//相当于执行Delete.delete(rootProject.buildDir)
delete rootProject.buildDir
}
buildscript闭包中对应工程运行所需依赖,分别是远程仓库依赖和远程插件依赖
repositories对应远程仓库的依赖
dependencies对应远程插件依赖。默认情况下只有classpath 'com.android.tools.build:gradle:3.4.1' Android Gradle插件。
引用插件规则:classpath 'groupId:artifactId:version'
allprojects闭包是工程项目中所有module的依赖
task clean任务栈是定义的task,执行删除任务。
module下的build.gradle
module下的build.gradle文件分为三部分:
1.apply plugin: 'com.android.application'
2.android {}闭包
3.dependencies {}闭包
1.apply plugin
apply plugin语句用来声明module是application工程还是library工程。
apply plugin 'com.android.application'代表这个一个application模块,可以直接运行,编译得到apk文件。
apply plugin 'com.android.library'代表这是一个库工程,不可以直接运行,只能依赖application运行,运行结束后得到aar文件。
2.android {}
android {}用来配置项目构建的各项属性
2.1signingConfigs{}闭包
存放的是签名相关的信息
signingConfigs {
release版本
release {
storeFile file('E:\\stydy\\AndroidGradle\\keystore.jks')
storePassword '123456'
keyAlias = 'key0'
keyPassword '123456'
}
debug版本
debug {
//签名文件路径
storeFile file('E:\\stydy\\AndroidGradle\\keystore.jks')
//签名文件密码
storePassword '123456'
//key别名
keyAlias = 'key0'
//key密码
keyPassword '123456'
}
}
signingConfigs可以通过手动配置,可以借助AS配置。AS配置流程如下:
File -> Project Structure -> Modules -> Signing Configs栏目下 -> +号创建点击ok后 自动配置。
配置完成后可以在File -> Project Structure -> Builde Variants中看到对应的type。选择对应的type可以配置相应的属性。
2.2 compileSdkVersion
编译时设置的Android版本
2.3 buildToolsVersion
设置编译时构建的工具版本
2.4defaultConfig {}闭包
defaultConfig {
applicationId "com.xj.androidgradle"
minSdkVersion 15
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
applicationId 项目包名
minSdkVersion支持的最小sdk版本 低于这个版本安装不了
targetSdkVersion 项目的目标版本 设置改属性,系统将为此目标版本配置对应的特性。系统平台对应的特性需要该属性大于或者等于对应特性支持的版本号。否则不会生效。
versionCode 版本号
versionName 版本名称
testInstrumentationRunner 表明AndroidJUnitRunner进行单元测试
2.5 buildTypes {}闭包
buildTypes闭包中有两个闭包分别是release与debug,对应release版本与debug版本。
buildTypes {
release {
minifyEnabled false //是否混淆
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'//混淆文件
buildConfigField("String","name","\"value\"")
signingConfig signingConfigs.release
//...
}
debug{
minifyEnabled false //是否混淆
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'//混淆文件
buildConfigField("String","name","\"value\"")
signingConfig signingConfigs.debug
debuggable true //是否允许断点调试
jniDebuggable true//是否允许jni调试
renderscriptDebuggable true //是否开启渲染脚本
zipAlignEnabled true //是否开启zip压缩 减少包体积
pseudoLocalesEnabled false//伪语言环境
applicationIdSuffix ".xxx"//包名增加后缀
versionNameSuffix "xxx"//版本号增加后缀
}
}
minifyEnabled 是否启用混淆,默认false
proguardFiles 混淆文件配置 proguard-android-optimize.txt默认的混淆配置,proguard-rules.pro工程特殊的混淆配置
buildConfigField定义字段供代码调用。注意String格式的值需要加上转义符,不然会报错。
signingConfig签名信息
debuggable是否允许断点调试
jniDebuggable是否允许JNI代码调试
renderscriptDebuggable是否开心渲染脚本
renderscriptOptimLevel 渲染脚本等级 默认3
zipAlignEnabled是否开启zip压缩,用于较少包体积
pseudoLocalesEnabled是否开启伪语言环境,用于国际化相关
applicationIdSuffix 包名加上后缀
versionNameSuffix 版本名加上后缀
编译完成后可以在BuildConfig类中看到相关信息
public final class BuildConfig {
public static final boolean DEBUG = Boolean.parseBoolean("true");
public static final String APPLICATION_ID = "com.xj.androidgradle.xxx";
public static final String BUILD_TYPE = "debug";
public static final String FLAVOR = "";
public static final int VERSION_CODE = 1;
public static final String VERSION_NAME = "1.0xxx";
// Fields from build type: debug
public static final String name = "sssss";
}
2.6sourceSets闭包:
用于配置工程相关的文件路径
sourceSets {
main{
jniLibs.srcDirs = ['libs']
manifest.srcFile 'src/main/AndroidManifest.xml'
}
}
2.7packagingOptions闭包
打包时对重复文件的处理
packagingOptions{//打包相关配置
//pickFirsts做用是 当有重复文件时 打包会报错 这样配置会使用第一个匹配的文件打包进入apk
//表示当apk中有重复的META-INF目录下有重复的LICENSE文件时 只用第一个 这样打包就不会报错
pickFirsts = ['META-INF/LICENSE']
//merges何必 当出现重复文件时 合并重复的文件 然后打包入apk
//合并重复文件
merge 'META-INF/LICENSE'
//移出相关的文件
exclude 'META-INF/services/javax.annotation.processing.Processor'
}
2.8 productFlavors多渠道打包
//维度,多渠道打包必备 有一个则productFlavors中的子项不需要携带dimension 属性,否则需要指明
flavorDimensions "version"
//定义多渠道
productFlavors{
baidu{
//manifest中设置占位 动态更改值
manifestPlaceholders = [UMENG_CHANNEL_VALUE:"baidu"]
//更改对应的渠道属性
applicationId ""
applicationIdSuffix ""
versionCode ""
versionNameSuffix ""
}
_360{
manifestPlaceholders = [UMENG_CHANNEL_VALUE:"_360"]
}
wangdoujia{
manifestPlaceholders = [UMENG_CHANNEL_VALUE:"wangdoujia"]
}
}
或者不需要在每个渠道中设置,通过统一的方式设置占位,这样就需要名称和值统一
productFlavors.each {
flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE:flavor.name]
}
2.9 lintOptions{}代码扫描分析
Lint是Android Studio提供的代码扫描工具,帮助我们提升代码质量
//程序在编译的时候会检查lint,有任何错误提示会停止build,配置下面开关控制Lint检测
lintOptions {
abortOnError false //即使报错也不会停止打包
checkReleaseBuilds false //打包release版本的时候进行检测
}
2.10 更改apk输出文件的名称
applicationVariants.all{
variant -> variant.outputs.each{
output -> output.outputFileName = "apk-${variant.name}-v${variant.versionName}-${buildTime()}.apk"
}
}
3.dependencies {}
dependencies {}闭包用来配置项目的依赖关系。依赖分为本地依赖,库工程依赖和远程依赖。
本地依赖可以对本地的jar文件或者目录添加依赖关系。
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation files('libs/foo.jar', 'libs/bar.jar')
库工程依赖可以将本地的库工程添加依赖。
implementation project(':mylibrary')
远程依赖将远程库中的工程添加依赖。
implementation 'com.example.android:app-magic:12.3'
上面其实是 implementation group: 'com.example.android', name: 'app-magic', version: '12.3' 简写
依赖字段:
implementation A工程依赖B,C工程依赖A A无法引用C的代码
api A工程依赖B,C工程依赖A A可以引用C的代码
compileOnly 编译时依赖,运行时不依赖
runtimeOnly 运行时依赖,编译时代码隔离
annotationProcessor 注解处理器
lintChecks 编译项目是Lint检查
lintPublish AAR lint检查
完整的build.gradle
apply plugin: 'com.android.application'
android {
signingConfigs {
release {
storeFile file('E:\\stydy\\AndroidGradle\\keystore.jks')
keyAlias = 'key0'
storePassword '123456'
keyPassword '123456'
}
debug {
storeFile file('E:\\stydy\\AndroidGradle\\keystore.jks')
storePassword '123456'
keyPassword '123456'
keyAlias = 'key0'
}
}
compileSdkVersion 29
buildToolsVersion "29.0.2"
defaultConfig {
applicationId "com.xj.androidgradle"
minSdkVersion 15
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false //是否混淆
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'//混淆文件
buildConfigField("String","name","\"value\"")
signingConfig signingConfigs.release
//...
}
debug{
minifyEnabled false //是否混淆
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'//混淆文件
buildConfigField("String","name","\"sssss\"")
signingConfig signingConfigs.debug
debuggable true //是否允许断点调试
jniDebuggable false//是否允许jni调试
renderscriptDebuggable false //是否开启渲染脚本
zipAlignEnabled false //是否开启zip压缩 减少包体积
pseudoLocalesEnabled false//伪语言环境
applicationIdSuffix ".xxx"//包名增加后缀
versionNameSuffix "xxx"//版本号增加后缀
}
}
sourceSets {
main{
jniLibs.srcDirs = ['libs']
manifest.srcFile 'src/main/AndroidManifest.xml'
}
}
packagingOptions{//打包相关配置
//pickFirsts做用是 当有重复文件时 打包会报错 这样配置会使用第一个匹配的文件打包进入apk
//表示当apk中有重复的META-INF目录下有重复的LICENSE文件时 只用第一个 这样打包就不会报错
pickFirsts = ['META-INF/LICENSE']
//merges何必 当出现重复文件时 合并重复的文件 然后打包入apk
//这个是有默认值得 merges = [] 这样会把默默认值去掉 所以我们用下面这种方式 在默认值后添加
merge 'META-INF/LICENSE'
//移出相关的文件
exclude 'META-INF/services/javax.annotation.processing.Processor'
}
flavorDimensions "version"
productFlavors{
baidu{
// manifestPlaceholders = [UMENG_CHANNEL_VALUE:"baidu"]
// applicationId ""
// applicationIdSuffix ""
// versionCode ""
// versionNameSuffix ""
}
_360{
// manifestPlaceholders = [UMENG_CHANNEL_VALUE:"_360"]
}
wangdoujia{
// manifestPlaceholders = [UMENG_CHANNEL_VALUE:"wangdoujia"]
}
}
productFlavors.each {
flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE:flavor.name]
}
applicationVariants.all{
variant -> variant.outputs.each{
output -> output.outputFileName = "apk-${variant.name}-v${variant.versionName}-${buildTime()}.apk"
}
}
}
def buildTime(){
def date = new Date();
def formatDate = date.format("yyyy_MM_dd--HH:mm")
return formatDate
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}