Gradle for Android

第二篇( Build.gradle入門 )

在這一章,我們將學(xué)習(xí)以下內(nèi)容:

  • 理解Gradle文件
  • 編寫簡單的構(gòu)建任務(wù)
  • 自制構(gòu)建腳本

理解Gradle腳本

當(dāng)然我們現(xiàn)在討論的所有內(nèi)容都是基于Android studio的示姿,所以請先行下載相關(guān)工具斋配。當(dāng)我們創(chuàng)建一個新的工程浩嫌,Android studio會默認(rèn)為我們創(chuàng)建三個gradle文件,兩個build.gradle古胆,一個settings.gradle渐北,build.gradle分別放在了根目錄和moudle目錄下,下面是gradle文件的構(gòu)成圖:

 MyApp
   ├── build.gradle
   ├── settings.gradle
   └── app
       └── build.gradle

setting.gradle解析

當(dāng)你的app只有一個模塊的時候卧波,你的setting.gradle將會是這樣子的:

include ':app'

setting.gradle文件將會在初始化時期執(zhí)行时肿,關(guān)于初始化時期,可以查看上一篇博客幽勒,并且定義了哪一個模塊將會被構(gòu)建嗜侮。舉個例子,上述setting.gradle包含了app模塊啥容,setting.gradle是針對多模塊操作的锈颗,所以單獨的模塊工程完全可以刪除掉該文件。在這之后咪惠,Gradle會為我們創(chuàng)建一個Setting對象击吱,并為其包含必要的方法,你不必知道Settings類的詳細(xì)細(xì)節(jié)遥昧,但是你最好能夠知道這個概念覆醇。

根目錄的build.gradle

該gradle文件是定義在這個工程下的所有模塊的公共屬性朵纷,它默認(rèn)包含二個方法:

buildscript {
     repositories {
         jcenter() 
     }
      dependencies {
          classpath 'com.android.tools.build:gradle:1.2.3'
      }
}
allprojects {
     repositories {
          jcenter() 
     }
}

buildscript方法是定義了全局的相關(guān)屬性,repositories定義了jcenter作為倉庫永脓。一個倉庫代表著你的依賴包的來源袍辞,例如maven倉庫。dependencies用來定義構(gòu)建過程常摧。這意味著你不應(yīng)該在該方法體內(nèi)定義子模塊的依賴包搅吁,你僅僅需要定義默認(rèn)的Android插件就可以了,因為該插件可以讓你執(zhí)行相關(guān)Android的tasks落午。

allprojects方法可以用來定義各個模塊的默認(rèn)屬性谎懦,你可以不僅僅局限于默認(rèn)的配置,未來你可以自己創(chuàng)造tasks在allprojects方法體內(nèi)溃斋,這些tasks將會在所有模塊中可見界拦。

模塊內(nèi)的build.gradle

模塊內(nèi)的gradle文件只對該模塊起作用,而且其可以重寫任何的參數(shù)來自于根目錄下的gradle文件梗劫。該模塊文件應(yīng)該是這樣:

 apply plugin: 'com.android.application'
   android {
       compileSdkVersion 22
       buildToolsVersion "22.0.1"
       defaultConfig {
           applicationId "com.gradleforandroid.gettingstarted"
           minSdkVersion 14
           targetSdkVersion 22
           versionCode 1
           versionName "1.0"
       }
       buildTypes {
           release {
               minifyEnabled false
               proguardFiles getDefaultProguardFile
                ('proguard-android.txt'), 'proguard-rules.pro'
           }
        } 
    }
    dependencies {
       compile fileTree(dir: 'libs', include: ['*.jar'])
       compile 'com.android.support:appcompat-v7:22.2.0'
     }

插件

該文件的第一行是Android應(yīng)用插件享甸,該插件我們在上一篇博客已經(jīng)介紹過,其是google的Android開發(fā)團(tuán)隊編寫的插件梳侨,能夠提供所有關(guān)于Android應(yīng)用和依賴庫的構(gòu)建枪萄,打包和測試。

Android

該方法包含了所有的Android屬性猫妙,而唯一必須得屬性為compileSdkVersion和buildToolsVersion:

  • compileSdkVersion:編譯該app時候,你想使用到的api版本聚凹。
  • buildToolsVersion:構(gòu)建工具的版本號割坠。

構(gòu)建工具包含了很多實用的命令行命令,例如aapt,zipalign,dx等妒牙,這些命令能夠被用來產(chǎn)生多種多樣的應(yīng)用程序彼哼。你可以通過sdk manager來下載這些構(gòu)建工具。

defaultConfig方法包含了該app的核心屬性湘今,該屬性會重寫在AndroidManifest.xml中的對應(yīng)屬性敢朱。

defaultConfig {
       applicationId "com.gradleforandroid.gettingstarted"
       minSdkVersion 14
       targetSdkVersion 22
       versionCode 1
       versionName "1.0"
}

第一個屬性是applicationId,該屬性復(fù)寫了AndroidManifest文件中的包名package
name摩瞎,但是關(guān)于applicationId和package
name有一些不同拴签。在gradle被用來作為Android構(gòu)建工具之前,package
name在AndroidManifest.xml有兩個作用:其作為一個app的唯一標(biāo)示旗们,并且其被用在了R資源文件的包名蚓哩。

Gradle能夠很輕松的構(gòu)建不同版本的app,使用構(gòu)建變種。舉個例子上渴,其能夠很輕松的創(chuàng)建一個免費版本和付費版本的app岸梨。這兩個版本需要分隔的標(biāo)示碼喜颁,所以他們能夠以不同的app出現(xiàn)在各大應(yīng)用商店,當(dāng)然他們也能夠同時安裝在一個手機(jī)中曹阔。資源代碼和R文件必須擁有相同的包名半开,否則你的資源代碼將需要改變,這就是為什么Android開發(fā)團(tuán)隊要將package name的兩大功能拆分開赃份。在AndroidManifest文件中定義的package name依然被用來作為包名和R文件的包名寂拆。而applicationid將被用在設(shè)備和各大應(yīng)用商店中作為唯一的標(biāo)示。

接下來將是minSdkVersion和targetSdkVersion芥炭。這兩個和AndroidManifest中的<uses-sdk>很像漓库。minSdkVersion定義為最小支持api。

versionCode將會作為版本號標(biāo)示园蝠,而versionName毫無作用渺蒿。

所有的屬性都是重寫了AndroidManifest文件中的屬性,所以你沒必要在AndroidManifest中定義這些屬性了彪薛。

buildTypes方法定義了如何構(gòu)建不同版本的app茂装,我們將在下一篇博客中有所介紹。

依賴包

依賴模塊作為gradle默認(rèn)的屬性之一(這也是為什么其放在了Android的外面)善延,為你的app定義了所有的依賴包少态。默認(rèn)情況下,我們依賴了所有在libs文件下的jar文件易遣,同時包含了AppCompat這個aar文件彼妻。我們將會在下一篇博客中討論依賴的問題。

讓我們開始tasks吧

如果你想知道你多少tasks可以用豆茫,直接運行g(shù)radlew tasks侨歉,其會為你展示所有可用的tasks。當(dāng)你創(chuàng)建了一個Android工程揩魂,那么將包含Android tasks幽邓,build tasks,build setup tasks火脉,help tasks牵舵,install tasks,verification tasks等倦挂。

基本的tasks

android插件依賴于Java插件畸颅,而Java插件依賴于base插件。

base插件有基本的tasks生命周期和一些通用的屬性妒峦。

base插件定義了例如assemble和clean任務(wù)重斑,Java插件定義了check和build任務(wù),這兩個任務(wù)不在base插件中定義肯骇。

這些tasks的約定含義:

  • assemble: 集合所有的output
  • clean: 清除所有的output
  • check: 執(zhí)行所有的checks檢查窥浪,通常是unit測試和inst* rumentation測試
  • build: 執(zhí)行所有的assemble和check
  • Java插件同時也添加了source sets的概念祖很。

Android tasks

android插件繼承了這些基本tasks,并且實現(xiàn)了他們自己的行為:

  • assemble 針對每個版本創(chuàng)建一個apk
  • clean 刪除所有的構(gòu)建任務(wù),包含apk文件
  • check 執(zhí)行Lint檢查并且能夠在Lint檢測到錯誤后停止執(zhí)行腳本
  • build 執(zhí)行assemble和check

默認(rèn)情況下assemble tasks定義了assembleDebug和assembleRelease漾脂,當(dāng)然你還可以定義更多構(gòu)建版本假颇。除了這些tasks,android 插件也提供了一些新的tasks:

  • connectedCheck 在測試機(jī)上執(zhí)行所有測試任務(wù)
  • deviceCheck 執(zhí)行所有的測試在遠(yuǎn)程設(shè)備上
  • installDebug和installRelease 在設(shè)備上安裝一個特殊的版本
  • 所有的install task對應(yīng)有uninstall 任務(wù)

build task依賴于check任務(wù),但是不依賴于connectedCheck或者deviceCheck骨稿,執(zhí)行check任務(wù)的使用Lint會產(chǎn)生一些相關(guān)文件笨鸡,這些報告可以在app/build/outputs中查看:

android studio的tasks

你根本不必要去執(zhí)行g(shù)radle腳本在命令行中,Android studio有其對應(yīng)的工具:


image
image

在這個界面坦冠,你要做的就是雙擊了形耗。當(dāng)然你也可以在Android studio中打開命令行,執(zhí)行相關(guān)命令辙浑,具體操作就不介紹了激涤。


image
image

自定義構(gòu)建

當(dāng)你在Android studio中自定義了gradle文件,需要更新project:


image
image

其實該按鈕判呕,執(zhí)行了generateDebugSources tasks倦踢,該任務(wù)會生成所有必要的classes文件。

BuildConfig和resources
android {
    buildTypes {
        debug {
            buildConfigField "String", "API_URL",
               "\"http://test.example.com/api\""
               buildConfigField "boolean", "LOG_HTTP_CALLS", "true"
     }
       release {
            buildConfigField "String", "API_URL",
                "\"http://example.com/api\""
               buildConfigField "boolean", "LOG_HTTP_CALLS","false"
     } 
 }

類似這些定義的常量侠草,當(dāng)定義了這些屬性后辱挥,你完全可以在代碼中使用:BuildConfig.API_URL和BuildConfig.LOG_HTTP

最近,Android tools team也讓其里面定義string變?yōu)榭赡埽?/p>

android {
       buildTypes {
           debug {
               resValue "string", "app_name", "Example DEBUG"
           }
           release {
               resValue "string", "app_name", "Example"
            } 
       }
}

你可以在代碼中使用這些string边涕。其中“”不是必須得晤碘。

全局設(shè)置

如果你有很多模塊在一個工程下,你可以這么定義你的project文件功蜓。

allprojects {
       apply plugin: 'com.android.application'
       android {
           compileSdkVersion 22
           buildToolsVersion "22.0.1"
       }
 }

這只會在你的所有模塊都是Android app應(yīng)用的時候有效哼蛆。你需要添加Android 插件才能訪問Android的tasks。更好的做法是你在全局的gradle文件中定義一些屬性霞赫,然后再模塊中運用它們。比如你可以在根目錄下這么定義:

 ext {
       compileSdkVersion = 22
       buildToolsVersion = "22.0.1"
}  

那么你在子模塊中就可以使用這些屬性了:

android {
       compileSdkVersion rootProject.ext.compileSdkVersion
       buildToolsVersion rootProject.ext.buildToolsVersion
 }

Project properties文件

上述方法是一種辦法肥矢,當(dāng)然還有很多辦法:

  • ext方法

  • gradle.properties文件

  • -p參數(shù)

      ext {
                    local = 'Hello from build.gradle'
                  }
                     task printProperties << {
                     println local  // Local extra property
                     println propertiesFile // Property from file
                     if (project.hasProperty('cmd')) {
                         println cmd  // Command line property
                       }
                  }     
    

當(dāng)然你可以在gradle.properties中定義:

propertiesFile = Hello from gradle.properties

你也可以輸入命令行:

$ gradlew printProperties -Pcmd='Hello from the command line'
:printProperties
Hello from build.gradle
Hello from gradle.properties
Hello from the command line

總結(jié)

在這篇博客中端衰,我們細(xì)致的查看了Android studio生成的三個gradle文件,現(xiàn)在你應(yīng)該能夠自己去創(chuàng)建自己的gradle文件甘改,我們還學(xué)習(xí)了最基本的構(gòu)建任務(wù)旅东,學(xué)習(xí)了Android 插件以及其tasks。

在接下來的幾年里十艾,Android開發(fā)生態(tài)將會爆炸性增長抵代,很多有趣的依賴庫將會讓每個人去使用,在下一篇博客里面忘嫉,我們將看看我們能有幾種方式添加我們的依賴庫荤牍,這樣我們才能夠避免造輪子案腺。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市康吵,隨后出現(xiàn)的幾起案子劈榨,更是在濱河造成了極大的恐慌,老刑警劉巖晦嵌,帶你破解...
    沈念sama閱讀 222,378評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件同辣,死亡現(xiàn)場離奇詭異,居然都是意外死亡惭载,警方通過查閱死者的電腦和手機(jī)旱函,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,970評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來描滔,“玉大人棒妨,你說我怎么就攤上這事“橹浚” “怎么了靶衍?”我有些...
    開封第一講書人閱讀 168,983評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長茎芋。 經(jīng)常有香客問我颅眶,道長,這世上最難降的妖魔是什么田弥? 我笑而不...
    開封第一講書人閱讀 59,938評論 1 299
  • 正文 為了忘掉前任涛酗,我火速辦了婚禮,結(jié)果婚禮上偷厦,老公的妹妹穿的比我還像新娘商叹。我一直安慰自己,他們只是感情好只泼,可當(dāng)我...
    茶點故事閱讀 68,955評論 6 398
  • 文/花漫 我一把揭開白布剖笙。 她就那樣靜靜地躺著,像睡著了一般请唱。 火紅的嫁衣襯著肌膚如雪弥咪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,549評論 1 312
  • 那天十绑,我揣著相機(jī)與錄音聚至,去河邊找鬼。 笑死本橙,一個胖子當(dāng)著我的面吹牛扳躬,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 41,063評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼贷币,長吁一口氣:“原來是場噩夢啊……” “哼击胜!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起片择,我...
    開封第一講書人閱讀 39,991評論 0 277
  • 序言:老撾萬榮一對情侶失蹤潜的,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后字管,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體啰挪,經(jīng)...
    沈念sama閱讀 46,522評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,604評論 3 342
  • 正文 我和宋清朗相戀三年嘲叔,在試婚紗的時候發(fā)現(xiàn)自己被綠了亡呵。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,742評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡硫戈,死狀恐怖锰什,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情丁逝,我是刑警寧澤汁胆,帶...
    沈念sama閱讀 36,413評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站霜幼,受9級特大地震影響嫩码,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜罪既,卻給世界環(huán)境...
    茶點故事閱讀 42,094評論 3 335
  • 文/蒙蒙 一铸题、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧琢感,春花似錦丢间、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,572評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至柬甥,卻和暖如春墙牌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背暗甥。 一陣腳步聲響...
    開封第一講書人閱讀 33,671評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留捉捅,地道東北人撤防。 一個月前我還...
    沈念sama閱讀 49,159評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像棒口,于是被迫代替她去往敵國和親寄月。 傳聞我的和親對象是個殘疾皇子辜膝,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,747評論 2 361

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