android開發(fā) 之 Gradle以及編譯優(yōu)化

本文Demo的完整工程代碼, 參考這里的StudyPackage

目錄

什么是Gradle

雖然原文定義又長(zhǎng)又晦澀, 但是為了準(zhǔn)確性, 還是引用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.

介紹完"學(xué)院派"的定義, 我們來看看"世俗派"的定義

Gradle是一種構(gòu)建工具, 它可以幫你管理項(xiàng)目中的差異, 依賴, 編譯, 打包, 部署......, 你可以定義滿足自己需要的構(gòu)建邏輯, 寫入到build.gradle中供日后復(fù)用

更多可以參考如何通俗地理解 Gradle浮毯?

就我個(gè)人的理解

Gradle就是用來解決除Coding以外對(duì)開發(fā)的所有常見需求(差異, 依賴, 編譯, 打包, 部署......)

為什么是Gradle

工具總是會(huì)有很多種, 那為什么偏偏就是Gradle呢? Gradle官方的解釋如下

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

  • Tool Integrations - 集成開發(fā)工具

  • Robust Dependency Management - 強(qiáng)大的依賴管理

  • Powerful Yet Concise Logic - 簡(jiǎn)潔但強(qiáng)大的邏輯

  • High Performance Builds - 高性能構(gòu)建

  • Build Reporting - 編譯結(jié)果報(bào)告

介紹完"自賣自夸"的定義, 其實(shí)Marven與Gradle最核心的分歧在于

Marven基于XML, 而Gradle基于Groovy的DSL(Domain Specific Language) -- 一種圖靈完備的構(gòu)建語言

所以Gradle的表達(dá)更加

  • 簡(jiǎn)潔 - XML依賴的寫法很繁瑣, 而Gradle只要一句話, 例如
compile 'com.android.support:appcompat-v7:24.2.0'
  • 智能 - 例如Gradle支持動(dòng)態(tài)版本依賴, 例如
testCompile ‘junit:junit:4.+'

Gradle的安裝

使用Android Studio構(gòu)建項(xiàng)目時(shí), IDE會(huì)幫我們下載和安裝Gradle

  • Mac上會(huì)默認(rèn)下載到/Users/<用戶名>/.gradle/wrapper/dists目錄

  • Windows平臺(tái)會(huì)默認(rèn)下載到C:\Documents and Settings<用戶名>.gradle\wrapper\dists目錄

由于Gradle無法"正常訪問"導(dǎo)致Android Studio會(huì)經(jīng)常"假死", 所以可以離線下載(參考AndroidDevTools), 然后拷貝至相應(yīng)目錄

Gradle項(xiàng)目結(jié)構(gòu)

使用Android Studio創(chuàng)建的Gradle項(xiàng)目的典型目錄結(jié)構(gòu)如下

gradle_01.png

其中與Gradle相關(guān)的文件主要有

gradle_02.png

Gradle相關(guān)文件

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
}

根目錄配置文件中定義的是所有子模塊的公共配置, 例如: 倉(cāng)庫(kù)源為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" // 應(yīng)用包名
        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'
}

模塊的配置文件中定義的都是當(dāng)前模塊的Gradle配置

settings.gradle

這是全局的項(xiàng)目配置文件, 里面聲明了需要加入gradle的module, 例如

include ':app'

gradle.properties

gradle.properties是gradle的配置文件

其中可以定義一些常量供build.gradle使用, 比如可以配置簽名相關(guān)信息如keystore位置, 密碼, keyalias等, build.gradle就可以直接引用, 因此

gradle中的一些配置參數(shù)建議寫到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會(huì)自動(dòng)生成該該文件, 所以一般需要配置該文件, 只有當(dāng)不使用Android Studio時(shí), 才自己配置

該文件不需要添加到版本控制系統(tǒng)中

Gradle Wrapper

為什么要使用Gradle Wrapper

如果開發(fā)者配置了Gradle Wrapper, 那么在其他開發(fā)者構(gòu)建該項(xiàng)目時(shí), 可以直接執(zhí)行如下命令

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

當(dāng)用戶第一次執(zhí)行上面的命令時(shí), Wrapper會(huì)自動(dòng)地下載并安裝對(duì)應(yīng)版本的Gradle, 這樣

用戶不必自己下載讹挎、安裝、配置Gradle; 用戶進(jìn)行項(xiàng)目構(gòu)建時(shí)能夠確保使用正確的Gradle版本

Gradle Wrapper需要哪些文件

在配置了Wrapper的Gradle項(xiàng)目中, 有以下文件

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

其中g(shù)radler-wrapper.properties文件的內(nèi)容大概如下

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

以上文件都需要添加到版本控制系統(tǒng)中

Gradle Wrapper的基本使用

  • ./gradlew -v - 版本信息

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

  • ./gradlew build - 檢查依賴并編譯打包(注意這里會(huì)將debug页屠、release包都打出來)

  • ./gradlew assembleDebug - 編譯并打Debug包

  • ./gradlew assembleRelease - 編譯并打Release的包

關(guān)于更多GradleWrapper的使用, 可以參考幫助: ./gradlew -h

Gradle編譯優(yōu)化

這里的優(yōu)化方法主要參考Making Gradle builds faster

配置編譯選項(xiàng)

  • --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

這些配置選項(xiàng)還可以添加系統(tǒng)全局配置文件~/.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

經(jīng)過實(shí)際測(cè)試, 對(duì)編譯速度有明顯提升的主要還是--daemon

使用最新版本的Gradle

Offline work

如果項(xiàng)目的Gradle和依賴沒有更新, 還可以勾選Offline work來加快編譯速度

gradle_03.png

參考

更多文章, 請(qǐng)支持我的個(gè)人博客

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末竞阐,一起剝皮案震驚了整個(gè)濱河市缴饭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌骆莹,老刑警劉巖颗搂,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異汪疮,居然都是意外死亡峭火,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門智嚷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來卖丸,“玉大人,你說我怎么就攤上這事盏道∩越” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵猜嘱,是天一觀的道長(zhǎng)衅枫。 經(jīng)常有香客問我,道長(zhǎng)朗伶,這世上最難降的妖魔是什么弦撩? 我笑而不...
    開封第一講書人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮论皆,結(jié)果婚禮上益楼,老公的妹妹穿的比我還像新娘。我一直安慰自己点晴,他們只是感情好感凤,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著粒督,像睡著了一般陪竿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上屠橄,一...
    開封第一講書人閱讀 51,688評(píng)論 1 305
  • 那天族跛,我揣著相機(jī)與錄音,去河邊找鬼锐墙。 笑死礁哄,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的贮匕。 我是一名探鬼主播姐仅,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼花枫,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼刻盐!你這毒婦竟也來了掏膏?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤敦锌,失蹤者是張志新(化名)和其女友劉穎馒疹,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體乙墙,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡颖变,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了听想。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片腥刹。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖汉买,靈堂內(nèi)的尸體忽然破棺而出衔峰,到底是詐尸還是另有隱情,我是刑警寧澤蛙粘,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布垫卤,位于F島的核電站,受9級(jí)特大地震影響出牧,放射性物質(zhì)發(fā)生泄漏穴肘。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一舔痕、第九天 我趴在偏房一處隱蔽的房頂上張望评抚。 院中可真熱鬧,春花似錦赵讯、人聲如沸盈咳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)鱼响。三九已至,卻和暖如春组底,著一層夾襖步出監(jiān)牢的瞬間丈积,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來泰國(guó)打工债鸡, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留江滨,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓厌均,卻偏偏與公主長(zhǎng)得像唬滑,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容