现在的位置: 首页 > 移动开发> 正文
Android构建编译系统之Gradle Build
2013年08月13日 移动开发 暂无评论 ⁄ 被围观 1,272+

Google I/O 2013 大会推出了一款新的Android开发工具Android Studio IDE,与Eclipse相差不多,实际的开发选择哪一款随个人喜好,像我平时的开发都是以Eclipse为主,ant辅助进行构建,也支持了一种新的构建工具Gradle,Android Studio IDE内置的默认构建工具就是Gradle,关于Gradle的详细资料可以参照官方网站。本系列文章介绍了Android开发过程中的Gradle Build,共有7篇文章,由浅入深。

At Google I/O 2013 Google announced some new developer tools including the new Android Studio IDE, and a new build system based around Gradle. In this series we’ll have a look at the Gradle build system, and look at how to convert existing projects to use the new build system.

Previously on Styling Android we’ve looked at using Maven for automating your builds, and we saw how Maven’s dependency management system can make life much easier. When using Maven, it can be advantageous in many cases to have your own maven repository management system (such as Nexus) to which you can deploy build artifacts so that they can be used across multiple projects. Gradle supports Maven repositories for retrieving dependencies (as well as other mechanisms such as Ivy) which allows much easier migration from other build systems.

Similarly to Maven and Ant, the Gradle build system requires of some additional config files which provide the build definition. It is entirely possible to have any combination of Ant, Maven, and Gradle builds configured for a project without interfering with each other, so it is possible to gently transition over to the new build system. So you are able to use both in parallel until you have the Gradle build working as well as or better than your existing build.

We will cover how to convert existing projects to use Gradle later in this series, but we’ll start with creating a new project, and analysing what gets created in order to understand a little about how the new build system works. Android Studio is fully integrated with the Gradle build system, so let’s use that to create a new project. Select “File|New Project…”, then we’ll set up a basic project named “GradleTest” with a package name ofcom.stylingandroid.gradle with a minSDK of API7 (2.1 Eclair), a targetSDK of API16 (4.1 Jelly Bean), and compiled with API17 (4.2 Jelly Bean). The rest of the details are unimportant because we’re interested in the build configuration and directory structure, and not the actual code.

This creates a new directory tree with a root folder named “GradleTestProject” this top level directory is actually a project parent, which allows us to create a multi-module project containing a number of distinct components such as library projects and APK projects. The actual APK project that we just created resides within this and is named “GradleTest”.

To begin with, let’s look at the parent project. As well as the “GradleTest” sub-project that it contains, there are some other things here. First there is a “.idea’ folder and a files named “GradleTestProject.iml” which are both files specific to Android Studio. We’re not covering Android Studio here, so we’ll ignore those.

There is a file named “local.properties” which is essentially the same as “project.properties” in the Eclipse based build.

There are a couple of files named “gradlew” and “gradlew.bat”, and a folder named “gradle”. These are the components of a Gradle wrapper which gets included within our project. The purpose of the wrapper is to provide a Gradle runtime which is included within the project and enables anyone to check out the code and perform a build without having to first install Gradle. This also ensures that the correct version of Gradle is used to perform the build and using the wrapper to perform the build can often save a lot of problems if an incompatible version of Gradle is installed on the computer performing the build. The “gradlew” and “gradlew.bat” files are *nix and Windows (respectively) scripts to launch the wrapper.

Finally we have two files named “build.gradle” and “settings.gradle” which are the actual build configuration and we’ll look at these in greater detail later in the series.

For now let’s look at how we can perform a build from the command line. To do this we need to invoke the gradle wrapper by calling the appropriate wrapper script file: “gradlew” for Linux / MacOS; “gradlew.bat” for Windows. We need to supply the names of the tasks that we wish to perform. In this case we cant to do a “clean” (to remove any build artifacts from previous builds) followed by “assemble” which will build our project and produce an APK:

GradleTestProject >./gradlew clean assemble
The TaskContainer.add() method has been deprecated and is scheduled to be removed in Gradle 2.0. Please use the create() method instead.
:GradleTest:clean
:GradleTest:prepareDebugDependencies
:GradleTest:compileDebugAidl
:GradleTest:generateDebugBuildConfig
:GradleTest:mergeDebugAssets
:GradleTest:compileDebugRenderscript
:GradleTest:mergeDebugResources
:GradleTest:processDebugManifest
:GradleTest:processDebugResources
:GradleTest:compileDebug
:GradleTest:dexDebug
:GradleTest:processDebugJavaRes UP-TO-DATE
:GradleTest:validateDebugSigning
:GradleTest:packageDebug
:GradleTest:assembleDebug
:GradleTest:prepareReleaseDependencies
:GradleTest:compileReleaseAidl
:GradleTest:generateReleaseBuildConfig
:GradleTest:mergeReleaseAssets
:GradleTest:compileReleaseRenderscript
:GradleTest:mergeReleaseResources
:GradleTest:processReleaseManifest
:GradleTest:processReleaseResources
:GradleTest:compileRelease
:GradleTest:dexRelease
:GradleTest:processReleaseJavaRes UP-TO-DATE
:GradleTest:packageRelease
:GradleTest:assembleRelease
:GradleTest:assemble

BUILD SUCCESSFUL

Total time: 12.42 secs
GradleTestProject >

At a first glance, 12 seconds seems rather slow for a build of a really simple project with very little code in it. Fortunately there are a couple of little things that we can do to speed this up. The first is to make use of Gradle’s incremental build which, will perform a checksum upon each file to determine whether that file needs to be re-built, or whether we can reuse a build product from a previous build. When we do a “clean” we remove all previous build products, so just running “assemble” on it’s own will result in a much faster build the second time:

GradleTestProject >./gradlew assemble
The TaskContainer.add() method has been deprecated and is scheduled to be removed in Gradle 2.0. Please use the create() method instead.
:GradleTest:prepareDebugDependencies
:GradleTest:compileDebugAidl UP-TO-DATE
:GradleTest:generateDebugBuildConfig UP-TO-DATE
:GradleTest:mergeDebugAssets UP-TO-DATE
:GradleTest:compileDebugRenderscript UP-TO-DATE
:GradleTest:mergeDebugResources UP-TO-DATE
:GradleTest:processDebugManifest UP-TO-DATE
:GradleTest:processDebugResources UP-TO-DATE
:GradleTest:compileDebug UP-TO-DATE
:GradleTest:dexDebug UP-TO-DATE
:GradleTest:processDebugJavaRes UP-TO-DATE
:GradleTest:validateDebugSigning
:GradleTest:packageDebug UP-TO-DATE
:GradleTest:assembleDebug UP-TO-DATE
:GradleTest:prepareReleaseDependencies
:GradleTest:compileReleaseAidl UP-TO-DATE
:GradleTest:generateReleaseBuildConfig UP-TO-DATE
:GradleTest:mergeReleaseAssets UP-TO-DATE
:GradleTest:compileReleaseRenderscript UP-TO-DATE
:GradleTest:mergeReleaseResources UP-TO-DATE
:GradleTest:processReleaseManifest UP-TO-DATE
:GradleTest:processReleaseResources UP-TO-DATE
:GradleTest:compileRelease UP-TO-DATE
:GradleTest:dexRelease UP-TO-DATE
:GradleTest:processReleaseJavaRes UP-TO-DATE
:GradleTest:packageRelease UP-TO-DATE
:GradleTest:assembleRelease UP-TO-DATE
:GradleTest:assemble UP-TO-DATE

BUILD SUCCESSFUL

Total time: 4.059 secs
GradleTestProject >

Notice how many of the steps are followed by “UP-TO-DATE” which means that Gradle did not need to re-compile, or rebuild these components. The main overhead that’s left is that each time we run Gradle, it is having to initialise itself. We can actually tell Gradle to keep itself in memory, and each invocation from the command line will re-use this in-memory version of Gradle. We do this by specifying the “–daemon” flag on the command line. This makes little difference the first time we run it because Gradle still needs to be loaded to memory, but on the second invocation with this flag we get another performance improvement:

GradleTestProject >./gradlew assemble --daemon
The TaskContainer.add() method has been deprecated and is scheduled to be removed in Gradle 2.0. Please use the create() method instead.
:GradleTest:prepareDebugDependencies
:GradleTest:compileDebugAidl UP-TO-DATE
:GradleTest:generateDebugBuildConfig UP-TO-DATE
:GradleTest:mergeDebugAssets UP-TO-DATE
:GradleTest:compileDebugRenderscript UP-TO-DATE
:GradleTest:mergeDebugResources UP-TO-DATE
:GradleTest:processDebugManifest UP-TO-DATE
:GradleTest:processDebugResources UP-TO-DATE
:GradleTest:compileDebug UP-TO-DATE
:GradleTest:dexDebug UP-TO-DATE
:GradleTest:processDebugJavaRes UP-TO-DATE
:GradleTest:validateDebugSigning
:GradleTest:packageDebug UP-TO-DATE
:GradleTest:assembleDebug UP-TO-DATE
:GradleTest:prepareReleaseDependencies
:GradleTest:compileReleaseAidl UP-TO-DATE
:GradleTest:generateReleaseBuildConfig UP-TO-DATE
:GradleTest:mergeReleaseAssets UP-TO-DATE
:GradleTest:compileReleaseRenderscript UP-TO-DATE
:GradleTest:mergeReleaseResources UP-TO-DATE
:GradleTest:processReleaseManifest UP-TO-DATE
:GradleTest:processReleaseResources UP-TO-DATE
:GradleTest:compileRelease UP-TO-DATE
:GradleTest:dexRelease UP-TO-DATE
:GradleTest:processReleaseJavaRes UP-TO-DATE
:GradleTest:packageRelease UP-TO-DATE
:GradleTest:assembleRelease UP-TO-DATE
:GradleTest:assemble UP-TO-DATE

BUILD SUCCESSFUL

Total time: 1.852 secs
GradleTestProject >

So, we have a basic Gradle build defined and working from the command line, and have seen a couple of tricks for improving performance. In the next article we’ll start looking a little deeper in to the build to see what’s happening.

The source code for this article is available here.

文章节选

给我留言

留言无头像?


×
腾讯微博