- Gradle for Android
- Kevin Pelgrims
- 1327字
- 2021-07-16 13:41:21
Understanding the Gradle files
When creating a new project with Android Studio, three Gradle files are generated by default. Two of those files, settings.gradle
and build.gradle
, end up on the top level of the project. Another build.gradle
file is created in the Android app module. This is how the Gradle files are placed in the project:
MyApp ├── build.gradle ├── settings.gradle └── app └── build.gradle
These three files each serve their own purpose, which we will further look into in the upcoming sections.
The settings file
For a new project containing only an Android app, settings.gradle
looks like this:
include ':app'
The settings file is executed during the initialization phase, and defines which modules should be included in the build. In this example, the app
module is included. Single module projects do not necessarily require a settings file, but multimodule projects do; otherwise, Gradle does not know which modules to include.
Behind the scenes, Gradle creates a Settings
object for every settings file, and invokes the necessary methods from that object. You do not need to know the details of the Settings
class, but it is good to be aware of this.
Note
A full explanation of the Settings
class is out of the scope of this book. If you would like to know more, you can find a lot of information in the Gradle documentation (https://gradle.org/docs/current/dsl/org.gradle.api.initialization.Settings.html).
The top-level build file
The top-level build.gradle
file is where you can configure options that need to be applied to all the modules in the project. It contains two blocks by default:
buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:1.2.3' } } allprojects { repositories { jcenter() } }
The buildscript
block is where the actual build is configured. We looked at this briefly in Chapter 1, Getting Started with Gradle and Android Studio. The repositories
block configures JCenter as a repository. In this case, a repository means a source of dependencies or, in other words, a list of downloadable libraries that we can use in our apps and libraries. JCenter is a well-known Maven repository.
The dependencies
block is used to configure dependencies for the build process itself. This means that you should not include dependencies that you need for your applications or libraries in the top-level build file. The only dependency that is defined by default is the Android plugin for Gradle. This is required for every Android module, because it is this plugin that makes it possible to execute Android-related tasks.
The allprojects
block can be used to define properties that need to be applied to all modules. You can take it even further and create tasks in the allprojects
block. Those tasks will then be available in all modules.
Note
As soon as you use allprojects
, the modules are coupled to the project. This means that it will likely be impossible to build the modules separately, without the main project's build file. It might not seem like an issue at first, but later you might decide to separate an internal library into its own project, and then you will need to refactor your build files.
The module build file
The module-level build.gradle
file contains options that only apply to the Android app module. It can also override any options from the top-level build.gradle
file. The module build file looks like this:
apply plugin: 'com.android.application' android { compileSdkVersion 22 buildToolsVersion "22.0.1" defaultConfig { applicationId "com.gradleforandroid.gettingstarted" minSdkVersion 14 targetSdkVersion 22 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:22.2.0' }
We will take a detailed look at the three main blocks.
Plugin
The first line applies the Android application plugin, which is configured as a dependency in the top-level build file, which we discussed earlier. The Android plugin is written and maintained by the Android Tools team at Google, and provides all tasks needed to build, test, and package Android applications and libraries.
Android
The biggest part of the build file is the android
block. This block contains the entire Android-specific configuration, which is available through the Android plugin we applied earlier.
The only properties that are required are compileSdkVersion
and buildToolsVersion
:
- The first one,
compileSdkVersion
, is the API version of Android that you want to use to compile your app - The second one,
buildToolsVersion
, is the version of build tools and compilers to use
The build tools contain command-line utilities, such as aapt, zipalign, dx, and renderscript; which are used to produce the various intermediate artifacts that make up your application. You can download the build tools through the SDK Manager.
The defaultConfig
block configures core properties for the app. The properties in this block override the corresponding entries in the AndroidManifest.xml
manifest file:
defaultConfig { applicationId "com.gradleforandroid.gettingstarted" minSdkVersion 14 targetSdkVersion 22 versionCode 1 versionName "1.0" }
The first property in this block is applicationId
. This overrides the package name from the manifest file, but there are some differences between applicationId
and the package name. Before Gradle was used as the default Android build system, the package name in AndroidManifest.xml
had two purposes: it served as the unique identifier of an app, and it was used as the name for the package in the R resource class. Gradle makes it easier to create different versions of your app, using build variants. For example, it is very easy to make a free version and a paid version. These two versions need to have separate identifiers, so they appear as different apps on the Google Play Store, and can both be installed at the same time. The source code and generated R class, however, must retain the same package name at all times. Otherwise, all your source files would need to change, depending on the version you are building. That is why the Android Tools team has decoupled these two different usages of package name. The package, as defined in the manifest file, continues to be used in your source code and your R class, while the package name that is used by the device and Google Play as the unique identifier is now referred to as application id. This application ID will become a lot more interesting as we start experimenting with build types.
The next two properties in defaultConfig
are minSdkVersion
and targetSdkVersion
. Both of these should look familiar because they have always been defined in the manifest as part of the <uses-sdk>
element. The minSdkVersion
setting is used to configure the minimum API level required to run the app. The targetSdkVersion
setting informs the system that the app is tested on a specific version of Android, and that the operating system does not need to enable any forward-compatibility behavior. This has nothing to do with compileSdkVersion
that we saw earlier.
The versionCode
and versionName
also have the same function as in the manifest file, and define a version number and a user-friendly version name for your app.
All values in the build file will override the values in the manifest file. It is therefore not required to define them in the manifest file if you define them in build.gradle
. In case the build file does not contain a value, the manifest values will be used as a fallback.
The buildTypes
block is where you define how to build and package the different build types of your app. We will take a detailed look at build types in Chapter 4, Creating Build Variants.
Dependencies
The dependencies
block is a part of the standard Gradle configuration (that is why it is placed outside of the android
block) and defines all dependencies for an app or library. By default, a new Android app has a dependency on all the JAR files in the libs
directory. Depending on the options you select in the new project wizard, it might also depend on the AppCompat
library. We will discuss dependencies in Chapter 3, Managing Dependencies.