android开发 之 Gradle以及编译优化

本文Demo的完整工程代码, 参考这里的StudyPackage

目录

什么是Gradle

虽然原文定义又长又晦涩, 但是为了准确性, 还是引用Wiki中Gradle的定义如下

Gradle is an open source build automation system that builds upon the concepts of Apache Ant and Apache Maven and introduces a Groovy-based domain-specific language (DSL) instead of the XML form used by Apache Maven of declaring the project configuration.[2] Gradle uses a directed acyclic graph ("DAG") to determine the order in which tasks can be run.

介绍完"学院派"的定义, 我们来看看"世俗派"的定义

Gradle是一种构建工具, 它可以帮你管理项目中的差异, 依赖, 编译, 打包, 部署......, 你可以定义满足自己需要的构建逻辑, 写入到build.gradle中供日后复用

更多可以参考如何通俗地理解 Gradle?

就我个人的理解

Gradle就是用来解决除Coding以外对开发的所有常见需求(差异, 依赖, 编译, 打包, 部署......)

为什么是Gradle

工具总是会有很多种, 那为什么偏偏就是Gradle呢? Gradle官方的解释如下

  • Polyglot Builds - 支持多种语言(例如Java, Scala, Python, C/C++, Android, IOS and many many more)

  • Tool Integrations - 集成开发工具

  • Robust Dependency Management - 强大的依赖管理

  • Powerful Yet Concise Logic - 简洁但强大的逻辑

  • High Performance Builds - 高性能构建

  • Build Reporting - 编译结果报告

介绍完"自卖自夸"的定义, 其实Marven与Gradle最核心的分歧在于

Marven基于XML, 而Gradle基于Groovy的DSL(Domain Specific Language) -- 一种图灵完备的构建语言

所以Gradle的表达更加

  • 简洁 - XML依赖的写法很繁琐, 而Gradle只要一句话, 例如
compile 'com.android.support:appcompat-v7:24.2.0'
  • 智能 - 例如Gradle支持动态版本依赖, 例如
testCompile ‘junit:junit:4.+'

Gradle的安装

使用Android Studio构建项目时, IDE会帮我们下载和安装Gradle

  • Mac上会默认下载到/Users/<用户名>/.gradle/wrapper/dists目录

  • Windows平台会默认下载到C:\Documents and Settings<用户名>.gradle\wrapper\dists目录

由于Gradle无法"正常访问"导致Android Studio会经常"假死", 所以可以离线下载(参考AndroidDevTools), 然后拷贝至相应目录

Gradle项目结构

使用Android Studio创建的Gradle项目的典型目录结构如下

gradle_01.png

其中与Gradle相关的文件主要有

gradle_02.png

Gradle相关文件

build.gradle

build.gradle是Gradle的核心配置文件, 它一般分为两种

  • 根目录配置文件, 例如build.gradle(Project: StudyPackage)
buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.2.0'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

根目录配置文件中定义的是所有子模块的公共配置, 例如: 仓库源为jcenter(), android gradle plugin的版本

  • 模块的配置文件, 例如build.gradle(Module: app)
apply plugin: 'com.android.application' // 声明是Android程序

android {
    compileSdkVersion 24 // 编译SDK的版本
    buildToolsVersion "24.0.2" // build tools的版本
    defaultConfig {
        applicationId "com.example.yuanlin.studypackage" // 应用包名
        minSdkVersion 21
        targetSdkVersion 24
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false // 是否代码混淆
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' // 混淆文件的位置
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar']) // 编译libs目录下的所有jar包
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:24.2.0'
    testCompile 'junit:junit:4.12'
}

模块的配置文件中定义的都是当前模块的Gradle配置

settings.gradle

这是全局的项目配置文件, 里面声明了需要加入gradle的module, 例如

include ':app'

gradle.properties

gradle.properties是gradle的配置文件

其中可以定义一些常量供build.gradle使用, 比如可以配置签名相关信息如keystore位置, 密码, keyalias等, build.gradle就可以直接引用, 因此

gradle中的一些配置参数建议写到gradle.properties

例如google/iosched的gradle.properties中配置了

###############################################################################
# App variables.
###############################################################################
# If versions end in odd numbers they are development builds, even versions are release candidates.
# The AndroidManifest.xml must also be updated currently.
version_code = 333
version_name = 3.3.3

......

模块中的build.gradle就可以这样引用

......

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.1"

    defaultConfig {
        version "${version_code}"
        versionName "${version_name}"
        minSdkVersion 14
        targetSdkVersion 22
        
        ......
    }
}

......

local.properties

该文件描述的是SDK的路径, 例如

sdk.dir=/Users/yuanlin/Workspace/android-sdk

需要注意的是

  • Android Studio会自动生成该该文件, 所以一般需要配置该文件, 只有当不使用Android Studio时, 才自己配置

该文件不需要添加到版本控制系统中

Gradle Wrapper

为什么要使用Gradle Wrapper

如果开发者配置了Gradle Wrapper, 那么在其他开发者构建该项目时, 可以直接执行如下命令

./gradlew [task] // Mac OS/Linux
gradlew [task] // Windows

当用户第一次执行上面的命令时, Wrapper会自动地下载并安装对应版本的Gradle, 这样

用户不必自己下载、安装、配置Gradle; 用户进行项目构建时能够确保使用正确的Gradle版本

Gradle Wrapper需要哪些文件

在配置了Wrapper的Gradle项目中, 有以下文件

|--gradle
|---- wrapper
|---- gradle-wrapper.jar
|---- gradle-wrapper.properties
|--gradlew (Mac OS/Linux)
|--gradlew.bat (Windows)

其中gradler-wrapper.properties文件的内容大概如下

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip

以上文件都需要添加到版本控制系统中

Gradle Wrapper的基本使用

  • ./gradlew -v - 版本信息

  • ./gradlew clean - 清除build和app/build目录

  • ./gradlew build - 检查依赖并编译打包(注意这里会将debug、release包都打出来)

  • ./gradlew assembleDebug - 编译并打Debug包

  • ./gradlew assembleRelease - 编译并打Release的包

关于更多GradleWrapper的使用, 可以参考帮助: ./gradlew -h

Gradle编译优化

这里的优化方法主要参考Making Gradle builds faster

配置编译选项

  • --dry-run: Runs the builds with all task actions disabled

  • --configure-on-demand: Only relevant projects are configured in this build run. This means faster build for large multi-project builds

  • --daemon: Uses the Gradle daemon to run the build. Starts the daemon if not running

  • --parallel: Build projects in parallel. Gradle will attempt to determine the optimal number of executor threads to use

这些配置选项还可以添加系统全局配置文件~/.gradle/gradle.properties中

echo 'org.gradle.configureondemand=true' >> ~/.gradle/gradle.properties
echo 'org.gradle.daemon=true' >> ~/.gradle/gradle.properties
echo 'org.gradle.parallel=true' >> ~/.gradle/gradle.properties

经过实际测试, 对编译速度有明显提升的主要还是--daemon

使用最新版本的Gradle

Offline work

如果项目的Gradle和依赖没有更新, 还可以勾选Offline work来加快编译速度

gradle_03.png

参考

更多文章, 请支持我的个人博客

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容