Java 構建Gradle 逐漸出如今各個開源軟件中,特別是Android平臺。雖然工具無對錯用的好便可,可是美帝亡我之心不死,從ANT(純手動)到MAVEN(套餐模式)再到Gradle(半自動步槍),每一次都是赤裸裸的學習成本。爲了跟上Google大爺的腳步,也只能委屈本身了。html
本文將從幾個方面介紹Gradle:java
Groovy 是JVM上的一門語言,兼容Java,而且具備腳本語言的特性,至關於JAVA的擴展語言。這裏將從這幾方面介紹Groovy:mysql
Groovy的安裝比較簡單,僅僅幾步就完成了:android
一般在使用Groovy的時候,一份API文檔是至關重要的GroovyAPI。git
好比說Groovy的全部對象都集成GroovyObject,經過查看API文檔,就能夠知道幾個很是重要的方法:github
這些方法都是比較重要的,涉及到動態語言的特性。如spring
getProperty(String s) -> Groovy動態屬性讀取API setProperty(String s,Object o) -> Groovy動態屬性設置APIsql
經過這兩個API,就能夠在運行時動態添加/讀取屬性,而且也增強了閉包做用域的動態性。shell
Groovy 是一門兼容Java的語言,而且在Java的語言基礎上添加了一些動態語言的特性。**Groovy能夠當作是Java的擴展集合。**接下來,將會介紹一些Groovy特有的語法特性,這些特性在Gradle中大範圍的被使用,瞭解這些語法,利於對Gradle的學習。編程
Groovy 支持類型推斷,也就是定義變量的時候,不須要指定類型,統一使用def便可,如:
def name = "DARKGEM";
固然也能夠採用:
String name = "Hello World";
來定義變量了。
Groovy支持語句最後面不用添加分號(;)
def w1 = "Hello World"; def w2 = "Hello World"
這兩句語句是等價的。
在Groovy中,函數的參數也能夠不定義它的類型,而是採用直接聲明變量名便可,如:
void say1(content){ println content; } void say2(String content){ println content; }
上面兩個函數是等價的。
Groovy的函數,其實也不須要指定函數返回類型,經過def定義函數便可,如:
def add(a,b){ return a+b; } int add(a,b){ return a + b }
它們是等價的
Groovy 的函數,其實也不須要return關鍵字,它會將最後一句的運行結果表達式,做爲return的結果,如:
def add(a,b){ a + b } def add(a,b){ return a + b }
它們是等價的。
Groovy中對函數的調用,有時候(至少存在一個參數)能夠省略括號,這個特性使得Gradle腳本看起來更像是DSL了。如:
println "NO () CALL" println("NO () CALL")
它們是等價的。
可是有時候,是不能省略括號的
def func(){ println 'i am function' } func()//success func//error
由於func函數沒有參數,因此調用的時候,若是省略了括號,**則func會被認爲是屬性。**因此只能採用func()調用方式。
Groovy的註釋和Java同樣,支持 // 和 /**/ 的寫法,如:
// 這是單行注視 /** 這 是 多 行 注 釋 */
Groovy 支持Java字符串,也支持動態推斷[$表達式],如:
def name = 'DARKGEM' println 'I am $name' println "I am $name" println "I am ${name}" println "1 + 2 = ${1+2}" println ''' SELECT * FROM T_USER '''
輸出結果爲:
在Java中,最討厭的就是空指針的處理了,而groovy提供了比較優雅的判斷空值的語句(?),如:
option?.call() -> 其中option多是空指針對象
經過這種語句,就能夠當option==null的時候,不進行調用call方法,避免拋出NullPointException。
在Groovy中,優化了對集合的操做,避免了一些比較醜陋的語法出現。
經過Groovy的語法特性,能夠很是簡單的對List進行初始化和操做
def list = [1,2,3,"4"] //初始化爲ArrayList對象,而非 Object[] 對象類型 println list[3] == '4' // 直接讀取數組元素 println list.join(",") == '1,2,3,4' // 支持join操做 println list.count(2) == 1 // 統計List中數值爲2的元素個數 list[99] = '100' //直接賦值到第100的位置 println list.size == 100 // 此時List對象的元素爲100個
Groovy對Map類型,提供了很是簡單易用的語法特性:
def map = [:] //聲明瞭map對象 def map = [key1 : 'val1' , 'key2' : 'val2'] //初始化map對象 println map.key1 == 'val1' // 讀取key1元素 println map["key1"] == 'val1' //讀取key1元素,注意[]裏面須要爲字符串 map.key1 = 'change val1' // 修改key1的元素 map.key3 = 'val3' //添加新元素
若是一個函數的參數爲Map類型,那麼能夠採用以下的方式調用:
def func(Map m){ println m } func key1:'val1', key2:'val2' //免去了() 以及[] func([key1:'val1',key2:'val2']) //完整的調用格式
在Groovy中,支持Range類型,好比說
1..3 // 1-3 1..<5 // 1-4
這種寫法,一般和迭代合起來用。
Groovy中最具備表明性的語法特性就是閉包(closure),閉包在Groovy中是一等公民。經過閉包,咱們能夠省略不少代碼。咱們看一下閉包最基本的寫法:
def c = { println "it's closure" } c(); // it's closure
僅僅經過**{}**就編寫出一個閉包,很是的方便。而閉包的語法結構爲:
{ [param][,param]->code }
的格式。其中,默認參數的關鍵字爲it。如:
def c = { println it } c('hello') // hello
返回的結果和函數同樣能夠經過return指定,也能夠默認採用最後一句表達式的運行結果。如:
def c ={ 1 +2 } def c = { return 1+2 }
是等價的。
而閉包的調用,一般有三種方法:
而若是函數的參數爲閉包的話,就造成了以下的語法格式:
def func(Closure c){ c() } func { println 'run closure' }
是否是和Gradle的腳本很是的相似。
Groovy對迭代,提供了很是NB的支持,如:
println '-------------list-----------' def list = [1,2,3,4] list.each { println it } println '-------------map--------------' def map = [k1:'v1',k2:'v2'] map.each{k,v-> println "$k:$v" } println '-----------number range------------' for(def i in 1..4){ println i } println '-----------char range------------' for(def i in 'a'..'d'){ println i }
運行結果:
Groovy是支持類的,而且還具備本身的特性:
見一個類的聲明:
class DGM{ def a def b //add def add(){ println "a + b = ${a + b}" } } DGM rhs = new DGM(a:1,b:2) //初始化,注意不能省略括號 rhs.add(); //調用方法 println rhs.a //訪問a屬性,是經過內置函數getA()實現 println rhs.getA() //訪問內置函數getA
運行結果爲:
經過javap查看groovyc編譯成字節碼後的DGM.class文件,能夠看到默認的方法:
對象也能夠像函數同樣被調用 a();
class A{ public Object call(Object... args){ println 'callMe' } } A a = new A() a()
運行結果:
Groovy支持一個重要的特性就是操做符重載了,經過這個特性,能夠很是方便的完成一些經常使用的操做,如List讀取某個元素的數值等。下面介紹leftShift(<<)的重載:
def list = [1,2,3,4] list << 5 //添加5到list中 list << 6 //添加6到list中 println list
運行結果爲:
能夠發現,在gradle中常常出現task <<寫法,其實就是重載了leftShift函數。
Groovy是一門動態語言,它支持動態屬性。
class A{ def prop = [:] void setProperty(String propertyName, Object newValue){ prop[propertyName] = newValue } Object getProperty(String propertyName){ return prop[propertyName] } } A a = new A() a.a = 1; println a.a
運行截圖:
能夠發現:經過重載GroovyObject#setProperty/getProperty就實現了動態屬性的特性。這個特性在Gradle常常被使用。
這個特性,結合閉包的delegate機制,就能夠改變閉包的做用域。如:
class A{ def prop = [:] void setProperty(String propertyName, Object newValue){ prop[propertyName] = newValue } Object getProperty(String propertyName){ return prop[propertyName] } def func (Closure c){ c() } } def closure = { //運行函數 func { println 'run closure' } //經過動態屬性,設置新的屬性 newProperty = 'newValue' } //指向A對象 closure.delegate = new A() //做用域優先採用delegate closure.setResolveStrategy Closure.DELEGATE_FIRST //運行 closure() //讀取閉包中設置的屬性 println closure.delegate.newProperty
運行結果:
經過這種方法,Gradle就能夠動態的加載插件/任務/配置屬性,而且能夠直接調用方法/屬性。
針對調用的語法:
func('arg1','arg2')
也能夠省略括號(爲函數的時候,參數須要多餘一個)
func '1','2'
若函數的時候沒有參數,則須要添加括號
func()
若是編寫以下格式的語法,則認爲是查詢屬性
func //查詢屬性,而非調用
這點和shell語法有極大的不一樣。
groovy的處理調用方式以下:
三言兩語,仍是比較難全面的介紹Groovy語言的,可是經過上面這些語法特性,基本上可讓初學者能讀通Gradle腳本了。若是要深刻的使用Gradle,那麼增強Groovy語言的學習也是有必要的。這裏給幾點意見:
編寫完Groovy腳本後,能夠經過groovyc來編譯,獲取class文件,而後反編譯(jd-gui/javap)查看groovy是如何轉換爲java語言的,加深的groovy語言的理解。
api手冊不離手,多看看javadoc。
Gradle是一個基於Apache Ant和Apache Maven概念的項目自動化建構工具。它使用一種基於Groovy的特定領域語言(DSL)來聲明項目設置,拋棄了基於XML的各類繁瑣配置。
面向Java應用爲主。當前其支持的語言限於Java、Groovy和Scala,計劃將來將支持更多的語言。
gradle對多工程的構建支持很出色,工程依賴是gradle的第一公民
BY 百度百科
Gradle的安裝很是的簡單,只須要以下幾步既能夠完成:
運行截圖:
**注意Gradle支持任務簡寫:**好比說存在兩個任務 assembleDebug 和 assembleRelease, 咱們不須要所有輸入,只須要輸入 gradle assD便可運行 assembleDebug 任務。
Gradle 是一門基於Groovy語言的構建框架。gradle支持ant,maven構建方式,而且和ide能比較完美的整合。
一個 Gradle 構建項目是由若干個project組成,而一個project是由若干個task組成。
Project概念針對某一個構建項目。一個Project包含了若干Task, 依賴關係,配置屬性等。一般Project通過一系列過程後會產出構建成品,如jar,war等。注意:Gradle容許項目依賴
**而Task是屬於Project的,經過一系列的Task組合,咱們能夠構建一個項目。**好比說:Project要輸出一個jar,那麼task通常有編譯,打包等。經過組合task,完成了最終產出jar的構建。
任務之間經過dependsOn來決定構建依賴。好比說debug依賴classes任務,則調用gradle debug的時候,會優先執行classes任務。以下圖:
一般咱們說的構建,就是經過指定某一個項目下(多項目)的某個task(build)來執行一系列的構建task,最終獲取想要的結果,如jar,war。
一個gradle項目的基本結構爲:
其中,setting.gradle 爲: include 'ProjectA','ProjectB' 來指示包含的項目
build.gradle 文件是描述項目是如何構建的關鍵。一般這個文件描述了項目引用的插件(插件包含了某種特定類型的構建任務集合,如java,android),任務配置(源碼位置,依賴關係),第三方倉庫等信息。
settings.gradle 文件一般是描述項目中的一些基本配置,如通用的task,在多項目構建中settings.gradle 還須要描述被包含的項目。
gradle 的構建流程,通常會按照以下的過程:
在各個階段,咱們能夠經過Gradle提供的Hook API進行截取。如:gradle.taskGraph.whenReady
如今,咱們來實際編寫一些gradle腳本,加深理解。
首先,咱們創建一個文件夾命名爲gradle 而後,在目錄下建立一個build.gradle的文件 最後,在build.gradle中輸入:
//定義hello這個任務 task hello << { println 'Hello' } /** 能夠發現,上面的task,利用了操做符重載,其重載的API仍是doLast。 task hello { doLast{ println 'Hello' } } */ //定義world任務,而且依賴hello任務 task world(dependsOn:hello) <<{ println 'World' }
咱們能夠經過gradle tasks 查看全部被支持的任務,發現咱們剛剛添加的任務已經出如今任務列表中了。 咱們在gradle/目錄下,執行** gradle world **命令,運行結果爲:
gradle 支持動態任務,也就是說,咱們能夠在腳本運行的時候,定義任務:
5.times { task "task$it" <<{ println "$it" } }
運行命令 gradle tasks 查看全部的任務:
咱們能夠在task中,添加一些咱們自定義的屬性
task hello { ext { mark = 'darkgem' } } println hello.mark
運行結果:
這個實現的原理就是Groovy的動態屬性。
咱們能夠指定gradle的默認任務,如:
defaultTasks 'run' task compile <<{ println 'compile...' } task run(dependsOn:compile) <<{ println 'run....' }
這樣子,咱們直接輸入 gradle 就直接執行 run task:
Gradle 在不一樣階段準備完成後,會執行Hook API,讓用戶能夠有機會修改某些流程或者配置等,好比說:
task distribution << { println "We build the zip with version=$version" } task release(dependsOn: 'distribution') << { println 'We release now' } gradle.taskGraph.whenReady {taskGraph -> if (taskGraph.hasTask(release)) { version = '1.0' } else { version = '1.0-SNAPSHOT' } }
運行結果:
能夠發現不一樣的任務,就出現了不一樣的執行結果。
如今,來介紹一下多項目構建。目錄結構爲:
settings.gradle:
include 'ProjectA','ProjectB'
ProjectA#build.gradle
task taskA <<{ println 'taskA' }
ProjectB#build.gradle
task taskB <<{ println 'taskB' }
執行gradle tasks -all 結果爲:
咱們能夠發現,gradle 的task語法和以前咱們介紹的groovy語法有些區別,如:
task first<<{ println 'first' } task hello(dependsOn:'first') { println 'hello' }
這種寫法,使用groovy語法的標準,沒法分析出task究竟是什麼東西。其實呢,gradle爲了腳本寫的好看,作了一些特別的工做。 上述的語句,在gradle分析腳本後,會轉換爲:
task('first',{ doLast{ println 'hello' } }) task('hello',{ dependsOn 'first' println 'hello' });
這種格式。這樣子,一切就真相大白了。**說白了就是gradle實現了本身的語法糖。**而經過後面的閉包,配置了這個task的屬性,如依賴,後置處理等。這個原理涉及到Groovy的delegate機制。
經過 repositories{} 能夠配置maven,ivy,local倉庫。這樣子,在dependencies{}聲明的依賴就能夠經過repositories{}中指定的倉庫查詢到具體的JAR資源。
configurations{} 記錄着項目中各個分組(compile,runtime)的依賴信息。**這些依賴信息來自於:引用的插件,dependencies{第三方庫},sourceSets{源碼},自定義配置,任務的構建產品(JAR)等。**以下是一個簡單的自定義分組信息:
configurations.create('myCompile') dependencies{ myCompile fileTree('lib') }
這樣子,咱們就聲明瞭一個名字爲myCompile的依賴分組。
configurations{}主要的做用在於:
注意:如compile,runtime 之類的configuration已經默認的被添加到java插件中,因此通常狀況下不要使用這幾種configuration。
在gradle中dependencies{}是一等公民,它描述了configurations{}中分組依賴的第三方資源。咱們能夠把依賴簡單的分紅兩大類:
gradle依賴:主要是gradle運行的時候,須要加載一些插件,如android等,此時須要配置它。
項目編譯/運行依賴:編譯一個項目,一般須要依賴其餘項目或者JAR。
gradle依賴指定,一般在buildscript{}模塊中聲明,若是是一個多項目構建,則只須要在root目錄下的build.gradle中添加gradle依賴便可。好比說,android gradle依賴支持:
buildscript { repositories { mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:1.5.0' } }
這樣子就配置好了gradle的運行依賴,在使用的時候,調用 apply plugin: 'android' 既能夠引入android插件。
在編譯項目的時候,也常常出現依賴外部JAR,項目等狀況。此時,咱們只須要配置 dependencies 便可引入JAR。
dependencies { //for dependencies found in artifact repositories you can use //the group:name:version notation compile 'commons-lang:commons-lang:2.6' testCompile 'org.mockito:mockito:1.9.0-rc1' //map-style notation: compile group: 'com.google.code.guice', name: 'guice', version: '1.0' //declaring arbitrary files as dependencies compile files('hibernate.jar', 'libs/spring.jar') //putting all jars from 'libs' onto compile classpath compile fileTree('libs') // dependencies project compile project(':someProject') //dependencies project and select configuration configurationName project(path: ':projectA', configuration: 'someOtherConfiguration') }
一個Java項目,一般依賴的關係如上圖描述。值得注意的是,依賴倉庫的JAR寫法:
這種寫法,和MAVEN一致。
在編寫gradle腳本的時候,網上的配置有時候不能解決你手頭的問題,因此咱們須要求助於Gradle文檔。
首先,咱們須要理解,一個gradle腳本通過處理後其實最後就是一個Groovy的腳本,區別點爲:
理解了這兩點,咱們就基本上能夠抱着API編寫腳本了。下面將介紹gradle腳本如何和Gradle文檔對應起來。
build.gradle //此時做用域鏈爲Project //調用 Project#apply(Map map) 方法 apply plugin: 'java' /** 語法糖 task('hello',{ //此時,做用域鏈爲Task doLast { // 調用Task#doLast方法 println 'hello' } }) */ task hello { doLast{ println 'hello' } }
翻閱Gradle的文檔(DSL,Javadoc),咱們能夠查詢到其餘有用的API來支持咱們的gradle編程。
本小節大體的描述了一下gradle這個構建工具,而且和groovy語言作了一下對比。能夠發現,gradle腳本就是groovy的腳本。
一個JavaWeb的項目構建和一個普通Java項目的構建最大的區別在於:JavaWeb有固定的目錄結構。如圖:
因此,咱們只要把項目構建的結果class存放到classes/目錄下,就是一個標準的JavaEE項目了。
接下來,咱們來看看Gradle提供的Java plugin的任務流程:
能夠發現,咱們其實僅僅須要** classes task **便可完成對編譯完成的class輸出。
構建項目目錄,該項目的目錄相似eclipse提供的JavaEE目錄結構:
而構建的腳本以下:
//使用Java插件 apply plugin: 'java' //配置編譯選項 compileJava { options.encoding = 'UTF-8' sourceCompatibility = "1.6" targetCompatibility = "1.6" } //配置源碼信息 sourceSets { main { //指定main的源碼輸出位置 output.resourcesDir = output.classesDir = 'WebContent/WEB-INF/classes/' //源碼目錄 java.srcDir('src') //資源文件目錄 resources.srcDir('src') } } //配置依賴 dependencies { //LIB依賴 compile fileTree('WebContent/WEB-INF/lib/') //servlet api依賴 compile fileTree('jetty/') } //動態生成任務 ({ //屬性配置和 def props = [ JDBC_CLASS_NAME : ['com.mysql.jdbc.Driver', 'com.mysql.jdbc.Driver'], JDBC_URL : ['jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8', 'jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8'], JDBC_USR : ['root', 'root'], JDBC_PASSWD : ['root', 'root'], JDBC_MAX_ACTIVE : [10, 10], JDBC_INITIAL_SIZE: [1, 1], JDBC_MIN_IDLE : [5, 5] ] //動態生成任務的名稱,注意 props裏面的屬性和這個序列對應 ['debug', 'release'].eachWithIndex { val, idx -> task "$val"(dependsOn: 'classes') << { //將配置信息,寫入指定文件中 Properties properties = new Properties() File file = new File(sourceSets.main.output.resourcesDir, 'project.properties') OutputStream fos = new FileOutputStream(file) props.each { key, value -> properties.setProperty(key, String.valueOf(value[idx])) } properties.store(fos, String.format("mode=%s", val)); } } })();
經過這個腳本,咱們能夠構建出一個JAVAEE的項目,而且該腳本支持生產環境和測試環境不一樣配置的特色。而腳本中的API調用都來自於Gradle Java DSL Plugin的描述。
項目地址:javaee-framework
在 Google I/O 2013 大會上,發佈了一款新的Android工具--Android Studio 以及 Gradle 後,eclipse 和 ant 逐漸被google 拋棄了。如今android小組的構建工具都採用gradle,而且它對應的插件目前版本已經2.0了。
經過gradle構建android項目是很是簡單的。首先建立項目:
android create project -n Demo -a MainActivity -k org.darkgem -v 1.5.0 -t android-15 -g -p .
這樣子就建立了一個簡單的android gradle 項目。
可是由於gradle的版本兼容性的問題,因此咱們還須要修改一下build.gradle腳本:
//gradle初始化的時候,須要加載的資源指定 buildscript { repositories { mavenCentral() } //加載android gradle 插件JAR dependencies { classpath 'com.android.tools.build:gradle:1.5.0' } } //加載android 插件 apply plugin: 'android' android { //配置android sdk版本 compileSdkVersion 'android-15' //配置編譯工具版本 buildToolsVersion '23.0.2' }
而後咱們運行指令gradle build,進行構建。結果發現異常:
能夠發現,在運行task lint的時候,發生了異常,查看lint 報告:
能夠發現,實際上是由於local.properties文件中關於sdk.dir寫法出現問題,咱們修改一下就能夠了:
sdk.dir=D:\\Link\\android-sdk -> sdk.dir=D\:\\Link\\android-sdk
再次運行gradle build就能夠執行成功了。其輸出的apk在:
android lint是一款靜態代碼檢測工具,經過lint能夠在編譯期就能夠發現許多問題,如調用太新的API等。這個檢測是至關有必要的。因此不建議在腳本中添加:
android { lintOptions { abortOnError false } }
這會致使lint檢測無效。
值得注意的是:在Android Studio中,若是點擊Debug按鈕進行調試,是不會運行task lint的,因此須要用戶手動的調用 task lint,使得在開發的時候,就知道問題出如今哪裏。
gradle不像maven同樣,源碼和目錄這些都是固定位置的,咱們能夠經過配置,修改默認位置:
sourceSets{ main.setRoot('app') }
這樣子就把mian目錄,從默認位置的 src/main/ 提取到了 app下面。還能夠配置其餘的一些文件和目錄:
sourceSets { main { //mainifest文件 manifest.srcFile 'AndroidManifest.xml' //源碼目錄 java.srcDirs = ['src'] //源碼資源目錄 resources.srcDirs = ['src'] //aidl目錄 aidl.srcDirs = ['src'] //layout等資源目錄 res.srcDirs = ['res'] //assets目錄 assets.srcDirs = ['assets'] //SO文件目錄 jniLibs.srcDirs = ['libs'] } }
這樣子,就講該android項目的源碼目錄結構變成和eclipse同樣了。
android gradle的依賴管理和java同樣,只須要配置好 repositories{} 和 dependencies{} 便可。如:
//配置倉庫 repositories { mavenCentral() } //配置依賴 dependencies { //按照maven名稱加載jar compile 'com.google.guava:guava:11.0.2' //加載目錄下全部的jar compile fileTree(dir: 'libs', include: ['*.jar']) //多個文件 }
android的構建必不可少的就是簽名了,經過簽名。通常簽名分爲兩種:DEBUG 和 RELEASE ,因此通常只須要兩種類型的簽名便可:
android{ signingConfigs { debug { storeFile file("debug.keystore") } release { storeFile file("release.keystore") storePassword "darkgem" keyAlias "release" keyPassword "darkgem" } } buildTypes { //release類型配置 release { //指定使用哪一個簽名配置 signingConfig signingConfigs.release } } }
值得注意的是DEBUG簽名是固定格式的:
一般,咱們只須要拷貝~/.android/debug.keystore 便可。
爲了保護咱們的代碼,一般在發佈版本的時候進行代碼混淆處理:
buildTypes { release { minifyEnabled true proguardFile 'proguard-project.txt' } }
這樣子就在release的時候進行代碼混淆了。
值得注意的是:
下面給出一個比較完成的腳本,充分的考慮的測試環境和發佈環境配置等:
//gradle初始化腳本 buildscript { //第三方倉庫 repositories { mavenCentral() } //android gradle plugin 插件依賴 dependencies { classpath 'com.android.tools.build:gradle:1.5.0' } } //使用android 插件 apply plugin: 'android' android { //sdk 版本 compileSdkVersion 'android-15' //構建工具版本 buildToolsVersion '23.0.2' //源碼配置 sourceSets{ main.setRoot('app') } //簽名配置 signingConfigs { debug { storeFile file("debug.keystore") } release { storeFile file("release.keystore") storePassword "darkgem" keyAlias "release" keyPassword "darkgem" } } //構建類型 buildTypes { //測試版本 debug{ //測試版本對AndroidMainfest.xml 中關鍵字替換 //UMENG manifestPlaceholders = [UMENG_APPKEY: "56947a48e0f55a0635002c3a", UMENG_CHANNEL : "DARKGEM"] //在 BuildConfig中,添加自定義的屬性 //BUILD CONFIG buildConfigField "String", "MAIN_API_URL", "\"http://darkgem.org/api/v1/\"" } //發佈版本 release { //開啓混淆處理 minifyEnabled true //簽名引用 signingConfig signingConfigs.release //混淆文件 proguardFile 'proguard-project.txt' //發佈版本對AndroidMainfest.xml 中關鍵字替換 //UMENG manifestPlaceholders = [UMENG_APPKEY: "56947a48e0f55a0635002c3a", UMENG_CHANNEL : "DARKGEM"] //在 BuildConfig中,添加自定義的屬性 //BUILD CONFIG buildConfigField "String", "MAIN_API_URL", "\"http://darkgem.org/api/v1/\"" } } //javac 配置 compileOptions { encoding 'UTF-8' sourceCompatibility JavaVersion.VERSION_1_6 targetCompatibility JavaVersion.VERSION_1_6 } } //依賴 dependencies { compile fileTree(include: ['*.jar'], dir: 'app/libs/') }
項目地址:android-framework
現今,許多android開源項目都開始使用gradle進行構建了。特別是support-v7包中的View類。若是直接進行拷貝引入,你會發現很是的困難。此時,咱們須要藉助gradle多項目編譯了。其方法和以前介紹的gradle多項目同樣。
值得注意的點有:
由於最新的support-v7包是用最新的sdk編譯的,因此,若是你使用舊版本的sdk編譯項目的話,可能出現資源文件沒法解析之類錯誤。此時,你須要把sdk提供到最新便可。
一般,咱們只須要在root/build.gradle中引入android gradle插件依賴,不須要每個build.gradle都引入一次android gradle plugin的依賴。
多項目中,引入插件的時候,須要區分application和library。
這篇文章斷斷續續的寫了三天,算是把gradle基礎概念學習了一遍。獲得最重要的經驗就是:多看文檔。