理解Gradle文件
当用Android Studio创建一个新项目时,默认会生成三个Gradle文件。其中的两个文件settings.gradle和build.gradle位于项目的根目录。另外一个build.gradle文件则在Android app模块内被创建。
这三个文件每一个都有自己的用途,我们会在接下来的篇幅中进一步说明。
settings文件
对于一个只包含一个Android应用的新项目来说。settings.gradle应该是这样的:
include ':app'
settings文件在初始化阶段被执行,并且定义了哪些模块应该包含在构建内。在上面的代码中,app模块被包含在内。单模块项目不一定需要setting文件,但是多模块项目必须要setting文件,否则,Grad了不知道哪个模块应该包含在构建内。
在这背后,Grad了会为每个settings文件创建一个Settings对象,并调用该对象的相关方法。你不必直到Settings类的相关细节,但意识到这一点是非常好的。
顶层构建文件
在项目中,所有的模块的配置参数都应在顶层build.gradle文件中配置。默认情况下起包含如下代码:
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.3.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
}
}
实际构建配置在buildscript代码块内,repositories代码块将JCenter配置成一个仓库,在这种情况下,一个仓库就意味这一系列的依赖包,或者说,在我们应用和依赖项目中可以使用的一系列可下载的函数库。JCenter是一个很有名的Maven库。
dependencies代码块用于配置构建构建过程中的依赖包。这也意味着你不能将你的应用或者以来项目所要的依赖包包含在顶层构建文件中。默认情况下,唯一被定义的依赖包时Gradle的Android插件。每个Android模块都需要有Android插件,因为该插件可使其执行Android相关的任务。
allprojects代码块可以用来声明哪些需要被用于所有模块的属性。你甚至可以在allprojects中创建任务,这些任务最终会被运用到所有模块。
模块的构建文件
模块层的build.gradle文件的属性智能应用在Android app模块,他可以覆盖顶层build.gradle文件的任何属性。该文件的构建文件实例如下:
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.muheda.dataaccount"
minSdkVersion 21
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
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'
}
1.插件
第一行用到了Android应用插件,该插件在顶层构建文件中被配置成了依赖。谷歌的Android工具团队负责Android插件的编写和维护,并提供构建,测试和打包Android引用以及以来项目的所有任务。
2.Android
在稿件文件中,占比最大的时Android代码块。该代码块包含了全部的Android特有配置,这些特有配置之所以被使用,是因为之前我们使用了Android插件。
必须有的属性是:compileSdkVersion和buildToolsVersion;
compileSdkVersion:是有用来编译应用的Android API版本。
buildToolsVersion:是构建工具和编译器使用的版本号
构建工具包含命令行应用,如aapt,zipalign,dx和renderscript,这些都被用来在打包应用时生成各种中间产物。你可以通过SDK Manager下载构建工具。defaultConfig代码块用于配置应用的核心属性。此代码块中的属性可覆盖AndroidManifest.xml文件中对应的条目。
applicationId是这段代码中的第一个属性。该属性覆盖了manifest文件中的packagename,但applicationId和package name有一些不同。在Gradle被用作默认的Android构建系统之前,AndroidManifest.xml中的package name有两个用途:作为一个应用的唯一标志,以及在R资源类中被用作包名。使用构建variants,Gradle可更容易的常见不同版本的应用。例如,构建variants可以很容易的构建一个免费版和一个付费版。这两个版本需要有独立的标识符,这样他们才能在Google Play Store中以不同的应用出现,并且可以同时被安装。。然而,资源代码和生成的R类,必须在任何时候都保持相同的包名,否则,你的所有源文件都要随着你正在构建的版本而改变。这就是Android工具团队解耦了package name两种不同用法的原因。定义在manifest文件中的package,继续用在你的源代码和R类中,而之前被用作设备和Google Play唯一标识的package name,现在则被称为application id。在我们开始尝试不同的构建类型时,application id将会变得更加有趣。
在defaultCounfig中,接下来的两个属性是minSdkVersion和targetDdkVersion。这两个通常是< uses-sdk>标签的一部分,在mainfest中被定义。minSdkVersion被用来配置运行应用的最小API级别。targetSdkVersion用于通知系统,该应用已经在某个特定的Android版本通过测试,从而操作系统不必启用任何向前兼容行为。这和我们之前看到的compileSdkVersion没有任何关系。
versionCode和versionName在manifest文件中的作用相同,即为你的应用定义一个版本号和一个友好的版本名称。构建文件中的属性会全面覆盖manifest文件中的属性。因此,如果你在build.gradle中定义了他们,就没有必要再manifest文件中再去定义。如果构建文件不包含某个属性,那么manifest中的该属性就会被用作后备。
buildTypes代码块可用来定义如何构建和打包不同构建类型的应用。我们会在后面介绍。
3.依赖包
依赖代码块是标准Gradle配置的一部分(这就是起放在Android代码块之外的原因),其定义了一个应用或者依赖项目的所有依赖包。默认情况下,一个新的Android应用,再libs文件夹下对所有jar文件构成依赖。根据你在新建项目向导中的选择,其也可能依赖于AppCompat。
任务入门
要想知道在一个项目中有哪些任务可用,则可以运行gradlew tasks任务,该命令会打印出所有可用的任务。在新建的Android项目中,其会包括Android tasks,build tasks,build setup tasks,help tasks,install tasks,verification tasks和其他tasks。如果你不仅想看这些任务,还想看到他们之间的依赖,那么你可以运行gradlew tasks --all。该命令会试运行这些任务,在运行某个特定的任务时,打印出所有被执行的步骤。试运行实际上不会执行上述任何步骤,所以当运行某个特定的任务时,其会是一种安全的方式,让你能够预测将会发生什么。
基础任务
Gradle 的Android插件使用了Java基础插件,而Java基础插件有使用了基础插件。基础插件添加了任务的标准生命周期和一些共同约定的属性。基础插件定义了assemble和clean任务,Java插件定义了check和buildtasks。在基础插件中,这些任务即不被实现,也不执行任何操作。他们被用来定义插件之间的约定,即添加事件工作的任务。
- assemble:集合项目的输出。
- clean:清理项目的输出。
- check:运行所有检查,通常是单元测试和集成测试。
- build:同时运行assemble和check。
Java基础插件添加了源集的概念。Android插件构建于这些约定,这样经验丰富的Gradle用户就可以可到这些暴露的任务。在这些基本的任务之上,Android插件也添加了很多Android特有的任务。
Android任务
Android插件扩展了基本任务,并实现了他们的行为。下面是Android环境下任务所作的事情:
- assemble:为每个构建版本创建一个APK
- clean:删除所有的构建内容,例如APK文件
- check:运行Lint检查,如果Lint发现一个问题,则可终止构建。
- build:同时运行assemble和check
assemble人们默认依赖于assembleDebug和assembleRelease,如果你添加了更多的构建类型,那么就会有更多的任务。这意味着,运行assemble将会触发每一个你所拥有的构建类型,并进行一次构建操作。
除了扩展这些任务之外,Android插件还添加了一些新的任务:
- connectedCheck:在连接设备或者模拟器上运行测试
- deviceCheck:一个占位任务,专门为其他插件在远端设备上运行测试
- installDebug和installRelease:在连接的设备或者模拟器上安装特定版本
- 所有的installtasks都会有相关的uninstall任务
构建任务依赖于check,而不是chonnectedCheck或者deviceCheck。这是因为构建任务只需保证正常的check,而无需一个连接的设备或者模拟器。运行check任务会生成一份Lint报告,Lint报告会包含所有的警告和错误,以及以分详细的说明和一个相关文档的链接。该报告在app/build/outputs目录下,名称为lint-results.html.
Lint将会检查哪些导致应用崩溃的致命问题。一旦发现有问题,Lint就会终止构建,并在命令行打印错误信息。Lint也会在app/build/outputs文件下生成一份叫做lint-results-release-fatal.html的报告。当你有多个问题时,浏览HTML报告将会比在命令行界面来回滚动更令人愉悦。其所提供的连接也非常有用,因为它们会指引你到问题的详细描述。
Android Studio
你不必经常在命令行界面运行Gradle任务。Android Studio有一个包含了所有可用任务的工具窗。该工具叫做Terminal。
未完。。。