Gradle for Android 第二篇( Build.gradle入門 )

這一系列暫不更新,相關技術討論,請移步微信羣,謝謝,但願你們多多支持!android

圖片描述

新年新氣象,奮鬥的一年,在這一章,咱們將學習如下內容:segmentfault

  • 理解Gradle文件api

  • 編寫簡單的構建任務微信

  • 自制構建腳本app

若是你尚未看grade for android系列的第一篇博客,請先查看:maven

Gradle for Android 第一篇( 從 Gradle 和 AS 開始 )工具

Gradle for Android 第三篇( 依賴管理 )學習

Gradle for Android 第四篇( 構建變體 )測試

Gradle for Android 第五篇( 多模塊構建 )gradle

Gradle for Android 第六篇( 測試)

Gradle for Android 第七篇( Groovy入門 )

理解Gradle腳本

固然咱們如今討論的全部內容都是基於Android studio的,因此請先行下載相關工具。當咱們建立一個新的工程,Android studio會默認爲咱們建立三個gradle文件,兩個build.gradle,一個settings.gradle,build.gradle分別放在了根目錄和moudle目錄下,下面是gradle文件的構成圖:

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

setting.gradle解析

當你的app只有一個模塊的時候,你的setting.gradle將會是這樣子的:

include ':app'

setting.gradle文件將會在初始化時期執行,關於初始化時期,能夠查看上一篇博客,而且定義了哪個模塊將會被構建。舉個例子,上述setting.gradle包含了app模塊,setting.gradle是針對多模塊操做的,因此單獨的模塊工程徹底能夠刪除掉該文件。在這以後,Gradle會爲咱們建立一個Setting對象,併爲其包含必要的方法,你沒必要知道Settings類的詳細細節,可是你最好可以知道這個概念。

根目錄的build.gradle

該gradle文件是定義在這個工程下的全部模塊的公共屬性,它默認包含二個方法:

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

buildscript方法是定義了全局的相關屬性,repositories定義了jcenter做爲倉庫。一個倉庫表明着你的依賴包的來源,例如maven倉庫。dependencies用來定義構建過程。這意味着你不該該在該方法體內定義子模塊的依賴包,你僅僅須要定義默認的Android插件就能夠了,由於該插件可讓你執行相關Android的tasks。

allprojects方法能夠用來定義各個模塊的默認屬性,你能夠不只僅侷限於默認的配置,將來你能夠本身創造tasks在allprojects方法體內,這些tasks將會在全部模塊中可見。

模塊內的build.gradle

模塊內的gradle文件只對該模塊起做用,並且其能夠重寫任何的參數來自於根目錄下的gradle文件。該模塊文件應該是這樣:

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應用插件,該插件咱們在上一篇博客已經介紹過,其是google的Android開發團隊編寫的插件,可以提供全部關於Android應用和依賴庫的構建,打包和測試。

Android

該方法包含了全部的Android屬性,而惟一必須得屬性爲compileSdkVersion和buildToolsVersion:

  • compileSdkVersion:編譯該app時候,你想使用到的api版本。

  • buildToolsVersion:構建工具的版本號。

構建工具包含了不少實用的命令行命令,例如aapt,zipalign,dx等,這些命令可以被用來產生多種多樣的應用程序。你能夠經過sdk manager來下載這些構建工具。

defaultConfig方法包含了該app的核心屬性,該屬性會重寫在AndroidManifest.xml中的對應屬性。

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

第一個屬性是applicationId,該屬性複寫了AndroidManifest文件中的包名package
name,可是關於applicationId和package
name有一些不一樣。在gradle被用來做爲Android構建工具以前,package
name在AndroidManifest.xml有兩個做用:其做爲一個app的惟一標示,而且其被用在了R資源文件的包名。

Gradle可以很輕鬆的構建不一樣版本的app,使用構建變種。舉個例子,其可以很輕鬆的建立一個免費版本和付費版本的app。這兩個版本須要分隔的標示碼,因此他們可以以不一樣的app出如今各大應用商店,固然他們也可以同時安裝在一個手機中。資源代碼和R文件必須擁有相同的包名,不然你的資源代碼將須要改變,這就是爲何Android開發團隊要將package name的兩大功能拆分開。在AndroidManifest文件中定義的package name依然被用來做爲包名和R文件的包名。而applicationid將被用在設備和各大應用商店中做爲惟一的標示。

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

versionCode將會做爲版本號標示,而versionName毫無做用。

全部的屬性都是重寫了AndroidManifest文件中的屬性,因此你不必在AndroidManifest中定義這些屬性了。

buildTypes方法定義瞭如何構建不一樣版本的app,咱們將在下一篇博客中有所介紹。

依賴包

依賴模塊做爲gradle默認的屬性之一(這也是爲何其放在了Android的外面),爲你的app定義了全部的依賴包。默認狀況下,咱們依賴了全部在libs文件下的jar文件,同時包含了AppCompat這個aar文件。咱們將會在下一篇博客中討論依賴的問題。

讓咱們開始tasks吧

若是你想知道你多少tasks能夠用,直接運行gradlew tasks,其會爲你展現全部可用的tasks。當你建立了一個Android工程,那麼將包含Android tasks,build tasks,build setup tasks,help tasks,install tasks,verification tasks等。

基本的tasks

android插件依賴於Java插件,而Java插件依賴於base插件。

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

base插件定義了例如assemble和clean任務,Java插件定義了check和build任務,這兩個任務不在base插件中定義。

這些tasks的約定含義:

  • assemble: 集合全部的output

  • clean: 清除全部的output

  • check: 執行全部的checks檢查,一般是unit測試和instrumentation測試

  • build: 執行全部的assemble和check

Java插件同時也添加了source sets的概念。

Android tasks

android插件繼承了這些基本tasks,而且實現了他們本身的行爲:

  • assemble 針對每一個版本建立一個apk

  • clean 刪除全部的構建任務,包含apk文件

  • check 執行Lint檢查而且可以在Lint檢測到錯誤後中止執行腳本

  • build 執行assemble和check

默認狀況下assemble tasks定義了assembleDebug和assembleRelease,固然你還能夠定義更多構建版本。除了這些tasks,android 插件也提供了一些新的tasks:

  • connectedCheck 在測試機上執行全部測試任務

  • deviceCheck 執行全部的測試在遠程設備上

  • installDebug和installRelease 在設備上安裝一個特殊的版本

  • 全部的install task對應有uninstall 任務

build task依賴於check任務,可是不依賴於connectedCheck或者deviceCheck,執行check任務的使用Lint會產生一些相關文件,這些報告能夠在app/build/outputs中查看:圖片描述

android studio的tasks

你根本沒必要要去執行gradle腳本在命令行中,Android studio有其對應的工具:

圖片描述

在這個界面,你要作的就是雙擊了。固然你也能夠在Android studio中打開命令行,執行相關命令,具體操做就不介紹了。
圖片描述

自定義構建

當你在Android studio中自定義了gradle文件,須要更新project:

圖片描述

其實該按鈕,執行了generateDebugSources tasks,該任務會生成全部必要的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"
     } 
 }

相似這些定義的常量,當定義了這些屬性後,你徹底能夠在代碼中使用:BuildConfig.API_URL和BuildConfig.LOG_HTTP

最近,Android tools team也讓其裏面定義string變爲可能:

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

你能夠在代碼中使用這些string。其中「」不是必須得。

全局設置

若是你有不少模塊在一個工程下,你能夠這麼定義你的project文件。

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

這隻會在你的全部模塊都是Android app應用的時候有效。你須要添加Android 插件才能訪問Android的tasks。更好的作法是你在全局的gradle文件中定義一些屬性,而後再模塊中運用它們。好比你能夠在根目錄下這麼定義:

ext {
       compileSdkVersion = 22
       buildToolsVersion = "22.0.1"
}

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

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

Project properties文件

上述方法是一種辦法,固然還有不少辦法:

  • ext方法

  • gradle.properties文件

  • -p參數

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

固然你能夠在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

總結

在這篇博客中,咱們細緻的查看了Android studio生成的三個gradle文件,如今你應該可以本身去建立本身的gradle文件,咱們還學習了最基本的構建任務,學習了Android 插件以及其tasks。

在接下來的幾年裏,Android開發生態將會爆炸性增加,不少有趣的依賴庫將會讓每一個人去使用,在下一篇博客裏面,咱們將看看咱們能有幾種方式添加咱們的依賴庫,這樣咱們纔可以避免造輪子。

相關文章
相關標籤/搜索