[85→100] 在Android项目如何用好Gradle配置?

Android Studio是Google专门为Android开发推出的集成开发环境,当前最新的稳定版2.1.2,作为一个成熟稳定的工具,已经基本替代了Eclipse+ADT,成为Android开发的主流工具了。

Android Studio是Google开发的一款面向Android开发者的IDE,支持Windows、Mac、Linux等操作系统,基于流行的Java语言集成开发环境IntelliJ搭建而成。该IDE在2013年5月的Google I/O开发者大会上首次露面,当时的测试版各种莫名其妙的Bug,但是14年12月8日发布的版本是稳定版。Android Studio 1.0推出后,Google官方将逐步放弃对原来主要的Eclipse ADT的支持,并为Eclipse用户提供了工程迁移的解决办法。不过相信作为Developer的你上手AS 1.0以后你再也不愿意使用原来苦逼的Eclipse+ADT了,你会被AS的各种强大所吸引。

伴随AS而来的是项目自动化建构工具——Gradle。

Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化建构工具。它使用一种基于Groovy的特定领域语言(DSL)来声明项目设置,抛弃了基于XML的各种繁琐配置。

什么是项目自动化建构工具?

程序员编写的产物是代码,在Android里面就是Java文件和xml文件,而Android机器运行的是apk。怎么把 Java文件和xml文件 变成 apk文件文件呢?这就需要用到编译工具。(计算机专业里面有一门课,叫“编译原理”,就是专门来讲这中间过程发生了些什么。)

对Android,其编译工具放在sdk下面build-tools里面。


编译工具往往是一个又一个命令行工具,用起来很繁琐,而且其中大部分是内容是固定的,只有少部分跟随具体项目变化,为了节省程序员的工作,项目自动化建构工具应运而生。

最先出现Makefile,主要用在C/C++的项目中。

Makefile 文件描述了整个工程的编译、连接等规则。其中包括:工程中的哪些源文件需要编译以及如何编译、需要创建那些库文件以及如何创建这些库文件、如何最后产生我们想要的可执行文件。尽管看起来可能是很复杂的事情,但是为工程编写Makefile 的好处是能够使用一行命令来完成“自动化编译”,一旦提供一个(通常对于一个工程来说会是多个)正确的 Makefile。编译整个工程你所要做的唯一的一件事就是在shell 提示符下输入make命令。整个工程完全自动编译,极大提高了效率。

然后在java端出现了ANT

Apache Ant,是一个将软件编译、测试、部署等步骤联系在一起加以自动化的一个工具,大多用于Java环境中的软件开发。由Apache软件基金会所提供。
Ant构建文件是XML文件。每个构建文件定义一个唯一的项目(Project元素)。每个项目下可以定 义很多目标(target元素),这些目标之间可以有依赖关系。当执行这类目标时,需要执行他们所 依赖的目标。每个目标中可以定义多个任务,目标中还定义了所要执行的任务序列。Ant在构建目标时必须调 用所定义的任务。任务定义了Ant实际执行的命令。

后来大家觉得ANT中的组件依赖能跨网络使用就好了,于是出现Maven,Maven带来了强大的中央库,确保开发产物可以在互联网上相互依赖,极大地方便了开源组件的使用。再后来大家发现Maven配置太啰嗦了,于是Gradle产生了。

<dependencies>
    <dependency>
        <groupId>com.google.code.kaptcha</groupId>
        <artifactId>kaptcha</artifactId>
        <version>${kaptcha.version}</version>
        <classifier>jdk15</classifier>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
    </dependency>
</dependencies>

maven这么长的配置项等价于如下gradle配置。

dependencies {
    compile('org.springframework:spring-core:2.5.6')
    compile('org.springframework:spring-beans:2.5.6')
    compile('org.springframework:spring-context:2.5.6')
    compile('com.google.code.kaptcha:kaptcha:2.3:jdk15')
    testCompile('junit:junit:4.7')
}

Android中Gradle的基本构成

在AS打开Android项目,点击Project下浏览模式,选中Android模式


会看到,所有跟Gradle相关的文件被汇总到了一块:


这其中文件可以按照名字分为几类:

  1. settings.gradle:放下项目根目录下,用来确定子文件夹中哪一些是Gradle Module。比如图片中对应的Module如下
include ':app', ':Calendarlibrary'
include ':EaseUI'
include ':WXLikeVideoRecorderLib'
  1. build.gradle:有两类:
  • 放置在项目根目录下,是对整个项目的配置。主要是配置buildscript、allprojects中引用的仓库的地址和依赖。
  • 放置在Module目录下,是对单个Module的配置。主要是配置Android编译工具版本、sdk版本,app包名、versionCode等信息。
  1. gradle.properties:可以定义一些String键值对,供build.gradle使用,其位置有三类:
  • 放置在系统目录下,所有AS项目共享的配置。
  • 放置在项目根目录下:单个AS项目及其Module的配置。
  • 放置在Module目录下:单个Module的配置。

随着位置的细化,其权重也加强,所以如果每个配置在 系统、项目、Module下都有定义,那最后起作用的是Module下定义的值。

  1. gradle-wrapper.properties:定义了gradle使用的版本。

Android中Gradle配置的最佳应用

问题1:如何统一项目里所有模块用同一个版本Android sdk来编译。

利用gradle.properties,在项目根目录的下gradle.properties定义如下键值对:

ANDROID_BUILD_MIN_SDK_VERSION=15
ANDROID_BUILD_TARGET_SDK_VERSION=23
ANDROID_BUILD_TOOLS_VERSION=23.0.3
ANDROID_BUILD_SDK_VERSION=23

然后在各个Module中采用如下配置:

android {
    compileSdkVersion Integer.parseInt(project.ANDROID_BUILD_SDK_VERSION)
    buildToolsVersion project.ANDROID_BUILD_TOOLS_VERSION

    defaultConfig {
        minSdkVersion Integer.parseInt(project.ANDROID_BUILD_MIN_SDK_VERSION)
        targetSdkVersion Integer.parseInt(project.ANDROID_BUILD_TARGET_SDK_VERSION)
        versionCode Integer.parseInt(project.VERSION_CODE)
        versionName project.VERSION_NAME
    }

问题2:出现Gradle DSL method not found: 'android()'怎么办?

这个问题是Android配置修改的问题,有时候在Project Structure里面修改App的编译版本时,android {}被添加到了项目根目录的build.gradle里,而实际上应该是在Module目录的build.gradle里。

解决方式:删除项目根目录的build.gradleandroid {}即可。相关配置直接在Module目录的build.gradle手动修改。

问题3:打开github下载的工程很慢,怎么办?

这个问题大多是因为该工程gradle配置没有下载到本地,而下载gradle及其相关编译文件是非常慢的。

解决方式:

  1. 确定本地gradle的版本,比如下面的版本为2.2-all2.5-bin2.10-all

    Paste_Image.png

  2. 修改gradle-wrapper.properties应用的版本号

distributionUrl=http\://services.gradle.org/distributions/gradle-2.10-all.zip
  1. 确定Android Studio的版本,比如为2.1.2

  2. 修改项目的build.gradle

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.1.2'
    }
}

问题4:已经编译过工程,第二天打开还是很慢,怎么办?

原因:默认在online模式下,一天中首次打开AS,gradle会去各个数据源同步信息,这些数据源访问慢的时候,就显得很卡。打开offline模式即可。

参考

  1. Android Studio教程从入门到精通
  2. 百度百科·Gradle
  3. [Android分享] Maven、gradle、Ant、Eclipse IDE之间的关系

拓展阅读

  1. 从零开始的Android新项目2 - Gradle篇

Panda
2016-07-22

推荐阅读更多精彩内容