参考:https://juejin.cn/post/6844903933584883720
参考:https://blog.csdn.net/Deep_rooted/article/details/124764731
参考:https://blog.csdn.net/delete_you/article/details/129126328
顶级结构
目录 | 作用 |
---|---|
.gradle | 自动生成的,Gradle编译系统,版本由wrapper指定 |
.idea | 自动生成的,Android Studio IDE所需要的文件 |
gradle | 这个目录下包含gradle wrapper的配置文件,使用gradle wrapper的方式不需要提前将gradle下载好,而是会自动根据本地的缓存情况决定是否需要联网下载gradle。 |
.gitignore | 上传git 忽略文件 |
build.gradle | 项目的gradle构建脚本,通常是不需要修改的 |
gradle.properties | 这个文件是全局的gradle文件,在这里配置的属性将会影响到项目中所有gradle编译的脚本。 |
gradlew | 用来在命令行界面执行 gradle命令的,gradlew是在Linux和Mac系统使用的 |
gradlew.bat | 用来在命令行界面执行 gradle命令的,gradlew.bat是在Windows系统使用的 |
local.properties | 本地配置,这个文件用于指定android SDK路径,通常是自动生成的,不需要修改 |
settings.gradle | 这个文件用于指定项目中引用的模块 |
.gitignore
git忽略文件,有些规则,稍微了解一下
#代表是写注释
忽略文件/目录
folderName:直接写名字,代表忽略所有目录和文件,而且会自动搜索多级目录下面的同名文件夹和名录。
folderName/:名字+斜杠结尾,代表忽略目录,不忽略同名的文件。
ps:注意一下,目录和文件的区别,目录就是文件夹,在git不允许空文件夹提交,所以不会有提交一个空文件的情况,而有些文件是没有后缀名的,所以可能出现目录和文件重名的情况。
如下的目录
如果是folder忽略,则是folder目录,以及src/folder 和 src/folder文件都会被忽略。
如果是folder/忽略,则只有folder目录忽略,而src/folder 和 src/folder文件不会被忽略
├── folder
│ └── file1
└── src
├── folder
└── utils
└── folder
/folderName:斜杠开头表示相对于这个.gitignore所在目录搜索,不会自动搜索多级目录。
!表示取反
!folderName:!代表反向操作,不忽略。
常用通配符
代表通配符,比如.log,代表匹配error.log,logs/debug.log等所有目录下以.log结尾的
代表匹配中间目录,比如src//build,可以匹配到src/test/build,也可以匹配到src/current/build。
?问号匹配 ‘/’外的单个任意字符,比如access?.log将会匹配access0.log,access1.log,accessA.log
gradle.properties
在使用Android Studio新建Android项目之后,在项目根目录下会默认生成一个gradle.properties文件,它是由IDE自动生成的gradle.properties文件。是项目级别的Gradle配置文件,gradle.properties里面定义的属性是全局的,可以在各个模块的build.gradle里面直接引用.我们可以在里面做一些Gradle文件的全局性的配置,也可以将比较私密的信息放在里面,防止泄露。
常用的的配置
org.gradle.jvmargs=-Xmx5120m -XX:MaxPermSize=1280m -Dfile.encoding=UTF-8
#(JVM堆内存大小,要是想运行的快一些,就改大点,整个8192m啥的)
android.useAndroidX=true
# 标识当前 module 启用 Androidx ,当把android项目自动迁移到androidX,
AS会自动在这个文件加上这句
android.enableJetifier=true
# 表示将项目中使用的第三方库也迁移到 Androidx
org.gradle.daemon=true
#通过开启守护进程,下一次构建的时候,将会连接这个守护进程进行构建,
#而不是重新 fork 一个 gradle构建进程
org.gradle.configureondemand=true
#按需加载
org.gradle.parallel=true
#并行编译
org.gradle.caching=true
#开启 gradle 缓存
android.enableBuildCache=true
#开启依赖缓存,这个设置可以让Android Studio 会把依赖的 jar 或 arr 缓存到本地,并且把模块名称设置为 hash 值。每次编译生成的缓存在 $HOME/.android/build-cache
android.injected.testOnly=false
#解决真机无法安装测试包的报错,因为国内一些安卓手机制作商定制的
#Android 系统不允许安装含带这个属性的测试包。哪怕你使用 -t 参数通过 adb 安装也是不行的,这个很常见
android.useNewApkCreator=false
#声明使用旧的打包器解决 Android Studio 升级 3.6 之后,
#报错 Entry name 'AndroidManifest.xml' collided,
#因此禁用新版本打包工具,使用旧的打包工具
kotlin.incremental=true
kotlin.incremental.java=true
kotlin.incremental.js=true
#kotlin 增量编译
kotlin.caching.enabled=true
#kotlin 编译缓存
kotlin.parallel.tasks.in.project=true
#kotlin 并行编译
kotlin.code.style=official
# Kotlin code style for this project: "official" or "obsolete"
# 优化kapt
# 并行运行kapt1.2.60版本以上支持
kapt.use.worker.api=true
# 增量编译 kapt1.3.30版本以上支持
kapt.incremental.apt=true
# kapt avoiding 如果用kapt依赖的内容没有变化,会完全重用编译内容,省掉#`app:kaptGenerateStubsDebugKotlin`的时间
kapt.include.compile.classpath=false
build.gradle
旧版本
项目的gradle构建脚本,分为buildscript{},allprojects{},task clean(type: Delete){}这三块
// buildScript gradle的构建脚本
buildscript {
repositories {
google()
mavenCentral()
jcenter()
maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
}
dependencies {
// 指定gradle插件版本
classpath "com.android.tools.build:gradle:4.2.2"
}
}
// allprojects是对所有的项目配置
allprojects {
repositories {
google()
mavenCentral()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
- buildScript:buildscript{}闭包里是gradle脚本执行所需依赖,分别是对应的maven库和插件。
buildscript中的声明是gradle脚本自身需要使用的资源。可以声明的资源包括依赖项、第三方插件、maven 仓库地址等,gradle在执行脚本时,会优先执行buildscript代码块中的内容,然后才会执行剩余的build脚本。
- repositories:
代表仓库地址,常见参数:
google()“Google官方依赖存储库
mavencentral():由sonatype.org维护的Maven仓库
jcenter():由 bintray.com维护的Maven仓库
maven { url ‘http://maven.aliyun.com/nexus/content/groups/public/}:手动指定Maven仓库地址
JCenter() 与 mavenCenter()在完全不同的服务器上维护,由不同的人提供内容,两者之间毫无关系。在jcenter上有的可能 Maven Central 上没有,反之亦然
- dependcies:
dependices闭包代表声明下载所需要的依赖,类似maven工程pom.xml中 <dependencies>标签
classpath
添加 buildscript 本身需要的依赖。
implementation
一般是在在模块中的build.gradle中,dependencies 中添加的使应用程序所需要的依赖包,也就是项目运行所需要的东西
-
allprojects:allprojects{}闭包里是项目本身需要的依赖,比如项目所需的maven库。是对所有项目声明的配置
- repositories
声明所有项目声明的依赖仓库。和buildScript中意思相同。
- task clean(type: Delete){}:是运行gradle clean时,执行此处定义的task任务,该任务继承自Delete,删除根目录中的build目录。其中buildscript包含repositories闭包和dependencies闭包。
新版本
plugins {
id 'com.android.application' version '7.1.2' apply false
id 'com.android.library' version '7.1.2' apply false
}
task clean(type: Delete) {
delete rootProject.buildDir
}
2022年1月的Gradle7.1.0版本做的更新,如果你用的是小蜜蜂版本的Android Studio,创建的的项目,默认就是没有buildscript和allprojects的,之前的仓库配置被挪到Project下的setting.gradle里面了。
如果确实还是需要旧版本的buildscript{}内容,还是可以使用,放在plugins{}上面即可,例如
buildscript {
dependencies {
classpath 'com.yanzhenjie.andserver:plugin:2.1.10'
}
}
plugins {
id 'com.android.application' version '7.1.2' apply false
id 'com.android.library' version '7.1.2' apply false
}
task clean(type: Delete) {
delete rootProject.buildDir
}
local.properties
sdk.dir=AppData\Local\Android\Sdk
本地配置,这个文件用于指定android SDK路径,通常是自动生成的,不需要修改
seetings.gradle
存放于项目根目录下,此设置文件会定义项目级代码库设置,并告知 Gradle 在构建应用时应将哪些模块包含在内
// 依赖管理
// 定义远程或者本地仓库位置,gradle将会从这些仓库搜索并下载对应依赖以及相关内容
pluginManagement {
// 定义仓库
repositories {
gradlePluginPortal()
google() // google官方仓库
mavenCentral() // maven中心仓库,替代老版本的JCenter
}
// 定义解决方案,即对所下载的依赖做出的处理
resolutionStrategy{
eachPlugin{
if (requested.id.id == 'dagger.hilt.android.plugin'){
useModule("com.google.dagger:hilt-android-gradle-plugin:2.38.1")
}
}
}
}
// 定义所有模块的仓库位置
// 这是一项全局配置,对于单个模块仍然需要定义自己的build.gradle来设置!
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
}
}
// 根工程名称(即你创建该android项目时的名字)
rootProject.name = "Character"
// 定义模块目录所在位置
include ':app'
rootProject:配置的是当前的工程名
include:引用不同的moulde
moudle(App)目录
目录 | 作用 |
---|---|
buidl | 编译时生成 |
libs | 存放第三方的jar包 |
release | 存放打包文件,需要打包完成才有的文件夹 |
src | module源码所在目录 |
.gitignore | git源码管理文件 |
proguard-rules.pro | 指定代码混淆 |
build.gradle | app模块的gradle构建脚本 |
app.iml | intellij IDEA项目都会自动生成的,AS是基于IDEA开发的 |
build
和外层的build类似主要包含编译时自动生成的内容,其中在outputs文件夹下存放打包好的apk文件
libs
如果项目中是用了第三方的jar包,就需要把jar包放到libs目录下,然后jar包会被自动添加到构建路径(如集成百度地图sdk,把jar包放到libs目录。可以在build.gradle(app)文件中查看当前项目依赖)
release
存放打包文件,需要打包操作之后,选择路径才会生成
.gitignore
git源码管理文件,同最外层一样
proguard-rules.pro
指定混淆规则,需要和module的build.gradle里面android{}闭包里面buildTypes{}配合使用,是否打开混淆。(目前没有使用需求,后续补充)
build.gradle:
app模块的gradle构建脚本,总共有三块
apply:声明是Android程序
android:android{}闭包,这个闭包主要为了配置项目构建的各种属性
dependecies:dependencies{}闭包,该闭包定义了项目的依赖关系,一般项目都有三种依赖方式:本地依赖、库依赖和远程依赖。
大概build.gradle构建脚本如下
plugins {
id 'com.android.application'
}
android {
compileSdkVersion 33 // 编译Android工程的SDK版本
buildToolsVersion "33.0.0" // 构建Android工程所用的构建工具版本,Android Studio3.0后去除此项配置
defaultConfig {
applicationId "com.example.gradle_lifecycle"
minSdkVersion 21
targetSdkVersion 33
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false //是否启用混淆
// 混淆文件
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
//自动化打包配置
signingConfigs {// 自动化打包配置
release {// 线上环境
keyAlias 'test'
keyPassword '123456'
storeFile file('test.keystore')
storePassword '123456'
}
debug {// 开发环境
keyAlias 'test'
keyPassword '123456'
storeFile file('test.keystore')
storePassword '123456'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
// implemengtation 添加的使应用程序所需要的依赖包
implementation 'androidx.appcompat:appcompat:1.5.1'
implementation project(':mylibrary')
implementation fileTree(dir: 'libs', include: ['*.jar'])
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
- plugins{}:一般有两种值可选:
com.android.application 表示这是一个应用程序模块。可以直接运行。
com.android.library 表示这是一个库模块,只能作为代码库依附于别的应用程序模块来运行,打包得到的是.aar文件
-
android{}:android{}是Android Gradle插件提供的一个扩展类型,可以让我们自定义Android Gradle工程。
- compileSdkVersion:编译Android工程的SDK版本
- buildToolsVersion “23.0.1”:构建Android工程所用的构建工具版本
- defaultConfig{}:defaultConfig{}是默认的配置,是一个ProductFlavor(构建渠道),ProductFlavor允许我们根据不同的情况同时生成不同的APK包。defaultConfig闭包可以对项目的更多细节进行配置。
defaultConfig {
applicationId "com.example.gradle_lifecycle"
minSdkVersion 21
targetSdkVersion 33
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
- **applicationId** :应用ID,在Android设备和市场上,这个ID是你应用的唯一标识。不是包名,默认和包名一致。
- **midSdkVersion:**用于指定项目最低兼容的Android系统版本。midSdkVersion 21对应Android 5.0。表示安装应用程序的手机系统的版本必须要>=5.0
- **targetSdkVersion:**APP所使用这个所设定的版本及该版本前的所有特性。如果设置为22,那么23以及23以后的所有新特性、新功能和API新行为统统无视;只认识22以及22之前提供的功能和API行为。
- **versionCodeApp:**应用内部版本名称,自己看的,用来给设备程序识别版本。
- **versionNameAPP:**应用的版本名称。展示给消费者的版本号,代表应用程序的版本信息。
- buildTypes{}:生产/测试环境配置。
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 中添加了一个后缀,一般使用的不多
}
}
- **release {}:** 生产环境
- **minifyEnabled**:表明是否对代码进行混淆,true表示对代码进行混淆,false表示对代码不进行混淆,默认的是false。
- **proguardFiles**:指定混淆的规则文件,这里指定了proguard-android.txt文件和proguard-rules.pro文件两个文件,proguard-android.txt文件为默认的混淆文件,里面定义了一些通用的混淆规则。proguard-rules.pro文件位于当前项目的根目录下,可以在该文件中定义一些项目特有的混淆规则。
- **buildConfigField**:用于解决Beta版本服务和Release版本服务地址不同或者一些Log打印需求控制的。例如:配置buildConfigField("boolean", "LOG_DEBUG", "true"),这个方法接收三个非空的参数,第一个:确定值的类型,第二个:指定key的名字,第三个:传值,调用的时候BuildConfig.LOG_DEBUG即可调用。
- **debuggable**:表示是否支持断点调试,release默认为false,debug默认为true。
- **jniDebuggable**:表示是否可以调试NDK代码,使用lldb进行c和c++代码调试,release默认为false
- **signingConfig**:设置签名信息,通过signingConfigs.release或者signingConfigs.debug,配置相应的签名,但是添加此配置前必须先添加signingConfigs闭包,添加相应的签名信息。
- **renderscriptDebuggable**:表示是否开启渲染脚本就是一些c写的渲染方法,默认为false。
- **renderscriptOptimLevel**:表示渲染等级,默认是3。
- **pseudoLocalesEnabled**:是否在APK中生成伪语言环境,帮助国际化的东西,一般使用的不多。
- **applicationIdSuffix**:和defaultConfig中配置是一的,这里是在applicationId 中添加了一个后缀,一般使用的不多。
- **versionNameSuffix**:表示添加版本名称的后缀,一般使用的不多。
- **zipAlignEnabled**:表示是否对APK包执行ZIP对齐优化,减小zip体积,增加运行效率,release和debug默认都为true。
- **debug {}:**开发环境,关键参数同生产环境
- signingConfigs{}:自动化打包配置
signingConfigs {// 自动化打包配置
release {// 线上环境
keyAlias 'test'
keyPassword '123456'
storeFile file('test.keystore')
storePassword '123456'
}
debug {// 开发环境
keyAlias 'test'
keyPassword '123456'
storeFile file('test.keystore')
storePassword '123456'
}
}
- **release {}:**线上环境
- keyAlias 'test':关键别名
- keyPassword '123456' :关键别名密码
- storeFile file('test.keystore') :位置
- storePassword '123456' //密码
- **debug {}:**开发环境,同线上环境
-
sourceSets{}:配置目录指向
- 配置 jniLibs.srcDirs = ['libs'],可以在Android studio的Android视图下生成jniLibs文件夹,可以方便我们存放jar包和库文件,其中Android视图下的jniLibs和project视图下的libs指向同一文件夹(app→libs),如下图所示:
sourceSets {//目录指向配置
main {
jniLibs.srcDirs = ['libs']//指定lib库目录
}
}
- packagingOptions{}闭包:打包时的相关配置,当项目中依赖的第三方库越来越多时,有可能会出现两个依赖库中存在同一个(名称)文件。如果这样,Gradle在打包时就会提示错误(警告)。那么就可以根据提示,然后使用以下方法将重复的文件剔除,比较常用的是通过exclude去除重复的文件,例如:
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{}:多个渠道配置这个配置是经常会使用到的,通常在适配多个渠道的时候,需要为特定的渠道做部分特殊的处理,比如设置不同的包名、应用名等。场景:当我们使用友盟统计时,通常需要设置一个渠道ID,那么我们就可以利用productFlavors来生成对应渠道信息的包,如:
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"]
}
//...
}
- lintOptions{}:代码扫描分析,Lint 是Android Studio 提供的 代码扫描分析工具,它可以帮助我们发现代码结构/质量问题,同时提供一些解决方案,而且这个过程不需要我们手写测试用例。Lint 发现的每个问题都有描述信息和等级(和测试发现 bug 很相似),我们可以很方便地定位问题,同时按照严重程度进行解决。
//程序在编译的时候会检查lint,有任何错误提示会停止build,我们可以关闭这个开关
lintOptions {
abortOnError false //即使报错也不会停止打包
checkReleaseBuilds false //打包release版本的时候进行检测
}
-
dependcies{}:该闭包定义了项目的依赖关系,一般项目都有三种依赖方式:本地依赖、库依赖和远程依赖。本地依赖可以对本地的jar包或目录添加依赖关系,库依赖可以对项目中的库模块添加依赖关系,远程依赖可以对jcener库上的开源项目添加依赖关系。
- 从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是一个本地依赖声明,表示将libs目录下所有.jar后缀的文件都添加到项目的构建路径当中。
- implementation 'com.android.support:appcompat-v7:27.1.1':implementation语句为 远程依赖声明,'com.android.support:appcompat-v7:27.1.1'为一个标准的远程依赖库格式,其中com.android.support为域名部分,用于区分不同公司的库;appcompat-v7为组件名称,用于区分同一个公司的不同库;27.1.1为版本号,用于区分同一个库的不同版本。加上这句声明后,Gradle在构建项目时会先检查一下本地是否已经缓存过该库,若没有缓存则自动联网下载,下载后自动添加到项目的构建路径中去。
- testImplementation和androidTestImplementation:表示声明测试用例库。