Original address: Http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Basic-Project
3. Basic Project
The build process for a Gradle project is defined in the Build.gradle file, located in the root directory of the project.
3.1 Simple Build files
One of the simplest gradle pure Java project Build.gradle files contains the following:
Apply plugin: ' java '
The Java plugin for Gradle is introduced here. This plugin provides all the things you need to build and test your Java application.
The Build.gradle file for the simplest Android project contains the following content:
Buildscript { repositories { mavencentral () } dependencies { classpath ' com.android.tools.build:gradle:0.11.1 ' } ' Apply plugin: ' Android ' Android { Compilesdkversion buildtoolsversion "19.0.0" }
This includes the 3 main parts of Android build file:
Buildscrip{...} This configures the code that drives the build process.
In this section, it declares the use of the Maven repository and declares a dependency path for a maven file. This file is a library containing the 0.11.1 version of the Android Gradle plugin.
Note: The configuration here only affects the code that controls the build process, without affecting the project source code. The project itself needs to declare its own warehouses and dependencies, which will be mentioned later.
Next, the Android plugin is added just like the Java plugin mentioned earlier.
Finally, andorid{...} The parameters required for all Android build processes are configured. This is also the entry point for the Android DSL.
By default, you only need to configure the target compilation SDK version and the compilation tool version, which is the Compilesdkversion and Buildtoolsversion properties.
This compliesdkversion property is equivalent to the target property in the Project.properites file in the old build system. This new property can specify a value of int or string type as the old target property.
Important: You can only add Android plugin. Adding Java plugin at the same time can cause build errors.
Note: You also need to add a local.properties file under the same path and use the Sdk.dir property to set the SDK path.
Alternatively, you can set the ANDROID_HOME environment variable, which makes no difference, and chooses one of the settings according to your own preferences.
3.2 Project Structure (item structure)
The basic build file that is mentioned above
requires a default folder structure. Gradle follows the concept of a contract over configuration, providing reasonable default configuration parameters whenever possible. The
Basic project starts with two components named "source Sets", which is main source code and test code. They are located at:
* src/main/
* src/androidtest/
Each of these existing folders corresponds to the corresponding source component.
for Java plugin and Android plugin, their Java source code and resource file paths are as follows:
* java/
* resources/
But for Android plugin, it also has the following unique file and folder structure:
* Androidmanifest.xml
* res/
* assets/
* aidl/
* rs/
* jni/
Note: src/androidtest/ Androidmanifest.xml is not needed, it will be created automatically.
3.2.1 Configuring the Structure (configuration item structure)
When the default project structure does not work, you may need to configure it. Depending on the gradle documentation, you can use the following methods to reconfigure the Java Project sourcesets:
Sourcesets { Main { java { srcdir ' Src/java ' } Resources { srcdir ' src/resources ' } } }
Note: Srcdir will be added to the specified existing source folder (this is not mentioned in the Gradle documentation, but it is actually done).
Instead of the default source code folder, you might want to replace the single srcdir with a srcdirs that can pass in an array of paths. The following is another different way to use the calling object:
sourcesets { main.java.srcDirs = [' Src/java '] main.resources.srcDirs = [' Src/resources '] }
For more information, refer to the section on Java pluign in the Gradle documentation.
Android plugin uses a similar syntax. But since it is using its own sourcesets, these configurations will be added to the Android object.
The following is an example that uses the main source code in the old project structure and androidtest the Sourceset component to the tests folder.
Android { Sourcesets { main { manifest.srcfile ' androidmanifest.xml ' java.srcdirs = [' src '] Resources.srcdirs = [' src '] aidl.srcdirs = [' src ' ] renderscript.srcdirs = [' src '] res.srcdirs = [' res '] assets.srcdirs = [' Assets '] } Androidtest.setroot (' Tests ') } }
Note: Because the old project structure places all the source files (java,aidl,renderscripthe and Java resource files) in the same directory, we need to remap these sourceset components to the SRC directory.
Note: the Setroot () method moves the entire component (including its subfolders) to a new folder. The example will move scr/androidtest/* to tests/*.
These are specific to Android and will not work if configured in Java sourcesets.
The above is also the migration required to migrate the old build system project to the new build system.
3.3 Build tasks (build Task)
3.3.1 General Tasks (common Task)
Adding a plugin to the build file will automatically create a series of buildtasks to execute (Note: Gradle is a task-driven build tool that builds on task-based). Both Java plugin and Android plugin create the following task:
* Assemble: This task will combine all the outputs of the project.
* Check: This task will perform all checks.
* Build: This task will perform all the work of assemble and check two task
* Clean: This task will empty the output of the project.
Actually assemble,check,build these three tasks without doing anything. They are just a task flag that tells Android plugin to add a task that actually needs to be executed to complete the work.
This allows you to invoke the same task without considering what type of project you are currently in, or what plugin is added to the current project.
For example, adding FindBugs plugin creates a new task and makes the check task dependent on the new task. When a check task is called, the new task is called first.
In the command-line environment, you can execute the following commands to get more high-level tasks:
Gradle Tasks
To view all the task lists and their dependencies, you can execute the following command:
Gradle Tasks--all
Note: Gradle automatically monitors all inputs and outputs of a task declaration.
Two times the build task is executed and the project has no changes during the period, Gradle will use up-to-date to notify all tasks. This means that the second build executes without requesting any task execution. This allows tasks to depend on each other without causing unwanted build requests to be executed.
3.3.2 Java Project Tasks (task for Java projects)
Java plugin primarily creates two tasks, depending on the main task (an identifying task):
* Assemble
* Jar: This task creates all outputs
* Check
* Test: This task performs all the tests.
The jar task itself directly or indirectly relies on other task:classes tasks that will be called to compile Java source code.
The testclasses task is used for compiling tests, but it is rarely called because the test task relies on it (similar to classes task).
Typically, you only need to call to assemble and check, and no other task is required.
You can view all the tasks of Java plugin in the Gradle documentation.
3.3.3 Android Tasks
Android plugin uses the same conventions to be compatible with other plugins and attaches its own identity task, including:
* Assemble:This task is used to assemble all the outputs in the project.
* Check:This task is used to perform all checks.
* Connectedcheck:This task will perform checks on a specified device or emulator, which can be executed on all connected devices at the same time.
* Devicecheck:The remote device is connected via APIs to perform the check, which is used on the CL server.
* Build:This task performs all the work of assemble and check.
* Clean:This task clears all output from the project.
These new identifying tasks are required to ensure that periodic checks can be performed without a device connection.
Note The build task does not depend on Devicecheck or Connectedcheck.
An Android project has at least two outputs: Debug apk (Debug version apk) and release apk (Release apk). Each output has its own identifying task so that it can be built separately.
* Assemble:
* Assembledebug
* Assemblerelease
They all depend on some other tasks to complete building an APK that requires multiple steps. Where assemble task relies on these two tasks, executing assemble will build two apk at the same time.
Tip: Gradle a task abbreviation that supports camel nomenclature on the command line terminal, for example, executing the gradle ar command is equivalent to executing gradle assemblerelease.
The check task also has its own dependencies:
* Check:
* Lint
* Connectedcheck:
* Connectedandroidtest
* Connecteduiautomatortest (not yet applied to)
* Devicecheck:This test relies on other plugins that implement test extension points when test is created.
Finally, as long as the task can be installed (those tasks that require signing), Android plugin installs or uninstalls for all build types (debug,release,test).
3.4 Basic Build Customization (basic building customization)
Android Plugin offers a large number of DSLs to customize most things directly from the build system.
3.4.1 Manifest Entries (Manifest attribute)
The manifest option can be configured with SDL:
* Minsdkversion
* Targetsdkversion
* Versionname
* PackageName
* Package Name for the test application
* Instrumentation Test Runner
For example:
Android { compilesdkversion buildtoolsversion "19.0.0" defaultconfig { Versioncode Versionname "2.0" minsdkversion ( targetsdkversion) }
All configurations are defined in the Defaultconfig element in the Android element.
The previous Android plugin version uses PackageName to configure the PackageName attribute in the manifest file. Starting with version 0.11.0, you need to use ApplicationID in the Build.gradle file to configure the PackageName attribute in the manifest file.
This is to eliminate the confusion caused by the application's PackageName (also the program's ID) and the Java package name.
The strength of the definition in the build file is that it is dynamic.
For example, you can read version information from one file or from another custom logic code:
Def computeversionname () { ... } Android { compilesdkversion buildtoolsversion "19.0.0" defaultconfig { Versioncode Versionname computeversionname () minsdkversion targetsdkversion + }
Note: Do not use a method name that may cause a conflict with the getter method in the given range. For example, in defaultconfig{...} Calling Getversionname () will automatically call the Defaultconfig.getversionname () method, and your custom Getversionname () method will be replaced.
If a property is not set using a DSL, some default property values will be used. The following table is the value that is likely to be used:
| Property Name |
Default value in DSL object |
Default value |
| Versioncode |
-1 |
Value from manifest if present |
| Versionname |
Null |
Value from manifest if present |
| Minsdkversion |
-1 |
Value from manifest if present |
| Targetsdkversion |
-1 |
Value from manifest if present |
| PackageName |
PackageName |
Value from manifest if present |
| Testpackagename |
Null |
App Package name + ". Test" |
| Testinstrumentationrunner |
Null |
Android.test.InstrumentationTestRunner |
| Signingconfig |
Null |
Null |
| Proguardfile |
N/A (set only) |
N/A (set only) |
| Proguardfiles |
N/A (set only) |
N/A (set only) |
If you use custom code logic to request these properties in a build script, the value of the second column is very important. For example, you might write:
if (Android.defaultConfig.testInstrumentationRunner = = null) { //assign a better default ... }
If this value remains null, the default value of the third column is actually replaced during the build execution. However, the default value is not included in the DSL element, so you cannot query this value.
Unless it is really needed, this is to prevent parsing the application's manifest file.
3.4.2 Build Types (build Type)
By default, Android plugin automatically builds the debug and release versions of the application to the project settings.
The differences between the two versions revolve around the ability to debug on a security device and how the APK is signed.
The debug version uses a common Name/password key value to sign automatically created digital certificates to prevent request information from appearing during the build process. The release version is not signed during the build process and needs to be signed later.
These configurations are configured through a BuildType object. By default, these two instances are created with a debug version and a release version, respectively.
Android plugin allows you to customize debug and release instances just as you would create other build types. This needs to be configured in the DSL container of Buildtypes:
Android { Buildtypes { Debug { applicationidsuffix ". Debug" } Jnidebug.initwith ( Buildtypes.debug) jnidebug { packagenamesuffix ". Jnidebug" jnidebugbuild True } } }
The code snippet above implements the following functions:
* Configure the default Debug build Type: Set the Debug version of the package name to <app Package>.debug so that you can install both the debug and release versions of the APK on a single device.
* A new build type named "Jnidebug" is created, and this build type is a copy of the debug build type.
* Continue to configure the Jnidebug build type, allow the use of JNI components, and also add a different package name suffix.
Creating a new build type is simply to add a new element under the BuildType tag, and you can configure it with Initwith () or by using a closure directly.
The following are some of the possible properties and default values:
| Property name |
Default values for debug |
Default values for Release/other |
| Debuggable |
Debuggable |
False |
| Jnidebugbuild |
False |
False |
| Renderscriptdebugbuild |
False |
False |
| Renderscriptoptimlevel |
3 |
3 |
| Packagenamesuffix |
Null |
Null |
| Versionnamesuffix |
Null |
Null |
| Signingconfig |
Android.signingConfigs.debug |
Null |
| Zipalign |
False |
True |
| Runproguard |
False |
False |
| Proguardfile |
N/A (set only) |
N/A (set only) |
| Proguardfiles |
N/A (set only) |
N/A (set only) |
In addition to the above attributes, Build type is also affected by project source code and resources:
A matching sourceset will be created automatically for each build type. The default path is:
src/<buildtypename>/
This means that the BuildType name cannot be either main or androidtest (because the two are enforced by plugin), and they must be unique to each other.
As with other sourceset settings, the source set path of Build type can be redirected again:
Android { sourceSets.jnidebug.setRoot (' Foo/jnidebug ') }
In addition, each build type will create a new assemble<buildtypename> task.
Assembledebug and assemblerelease Two tasks have been mentioned above, where the two tasks are created. When the debug and release build types are pre-created, their tasks automatically create the corresponding two tasks.
The Assemblejnidebug task is also implemented in the Build.gradle code snippet mentioned above. And assemble rely on assemblejnidebug as much as they rely on assembledebug and assemblerelease.
Tip: You can enter Gradle AJ under terminal to run Assemblejnidebug task.
Situations that may be used:
* Release mode is not required, only the permissions that are used in debug mode
* Custom DEBUG implementations
* Use different resources for debug mode (for example, when the value of a resource is determined by a bound certificate)
BuildType code and resources are used in the following ways:
* manifest will be blended into the app's manifest
* Code behavior is just another resource folder
* The resource will be superimposed into main's resource and replace the existing resource.
3.4.3 Signing Configurations (signature configuration)
The following is required for an application signature:
* One keystory
* One keystory password
* Alias of a key
* A key's password
* Storage Type
Location, key name, two passwords, and storage types together form a signature configuration.
By default, debug is configured to use one of the debug keystory. The debug keystory uses the default password and default key and the default key password.
The location of the debug keystory in $home/.android/debug.keystroe, if the corresponding location does not exist this file will be created automatically.
The Debug build type is automatically configured with the debug signature.
You can create additional configurations or customize the built-in default configuration. Configure by Signingconfigs this DSL container:
Android { Signingconfigs { Debug { storefile file ("Debug.keystore") } myconfig { storefile File ("Other.keystore") Storepassword "Android" Keyalias "Androiddebugkey" Keypassword "Android" } } buildtypes { foo { debuggable true jnidebugbuild true signingconfig Signingconfigs.myconfig }}}
The code snippet above modifies the path of the debug keystory to the root of the project. In this example, this will automatically affect other build types that use the debug build type.
A new single Config (signature configuration) and a new build type with this new signature configuration are also created here.
Note: Only the default path of debug keystory is not present when it is created automatically. Changing the path of the debug keystory does not automatically create a debug keystory under the new path. If you create a new signconfig with a different name, but use the default debug KeyStore path to create a signingconing with a non-default name, the debug keystory will still be created under the default path. In other words, the automatic creation is based on the path of the keystory, not the name of the configuration.
Note: Although the relative path of the project root is often used as the path to the KeyStore, the absolute path can also be used, although this is not recommended (except for the automatically created debug KeyStore).
Note: If you add these files to the version Control tool, you may not want to write the passwords directly to these files. The following stack overflow link provides a way to get a password from a console or environment variable:
Http://stackoverflow.com/questions/18328730/how-to-create-a-release-signed-apk-file-using-gradle
We'll also add more details to this guide later.
3.4.4 Running Proguard (running Proguard)
Support for Proguard has started since Gradle Plugin for Proguard version 4.10. The Proguard plug-in is automatically added. If the Runproguard property of the build type is set to True, the corresponding task will be created automatically.
Android { Buildtypes { release { runproguard true proguardfile getdefaultproguardfile (' Proguard-android.txt ') } } productflavors { flavor1 { } flavor2 { proguardfile ' Some-other-rules.txt '}} }
The release version will use the rule file declared in its build type, and product flavor (the customized version of the products) will use the rules file declared in the corresponding flavor.
Here are two default rule files:
* Proguard-android.txt
* Proguard-android-optimize.txt
These two files are in the SDK path. Use Getdefaultproguardfile () to get the full path to these files. They are all the same in addition to optimization.