新項目中,使用了Google I/O 2013發佈的新工具,使用Gradle構建android項目,而且在新版的Intellig IDEA以及google的Android Studio對其支持。本文就介紹一下怎麼使用gradle構建android項目,進行多個版本編譯。java
Gradle是以Groovy爲基礎,面向java應用,基於DSL語法的自動化構建工具。是google引入,替換ant和maven的新工具,其依賴兼容maven和ivy。
使用gradle的目的:android
更容易重用資源和代碼;git
能夠更容易建立不一樣的版本的程序,多個類型的apk包;github
更容易配置,擴展;api
更好的IDE集成;app
Gradle1.10或者更高版本,grale插件0.9或者更高版本.
android SDK須要有Build Tools 19.0.0以及更高版本maven
使用ide建立的gradle構建的項目,會自動建立一個build.gradle,以下:ide
buildscript { repositories { mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:0.9.0' } } apply plugin: 'android' android { compileSdkVersion 19 buildToolsVersion "19.0.0" }
能夠看到,構建文件主要有三個區域:工具
buildscript{...}測試
Configures the build script classpath for this project. 設置腳本的運行環境
apply plugin: 'android'
設置使用android插件構建項目
android{...}
設置編譯android項目的參數
一般會有如下任務:
assemble The task to assemble the output(s) of the project(輸出一個項目文件,android就是打包apk)
check The task to run all the checks.(運行檢查,檢查程序的錯誤,語法,等等)
build This task does both assemble and check (執行assemble和check)
clean This task cleans the output of the project(清理項目輸出文件)
上面的任務assemble,check,build實際上什麼都不作,他們其實都是其餘任務的集合。
執行一個任務的方式爲gradle 任務名
, 如gradle assemble
在android項目中還有connectedCheck(檢查鏈接的設備或模擬器),deviceCheck(檢查設備使用的api版本)
一般咱們的項目會有至少生成兩個版本,debug和release,咱們能夠用兩個任務assembleDebug和assembleRelease去分別生成兩個版本,也可使用assemble一會兒生成兩個版本。
gradle支持任務名縮寫,在咱們執行gradle assembleRelease的時候,能夠用gradle aR代替。
咱們能夠在build.gradle文件中配置咱們的程序版本等信息,從而能夠生成多個版本的程序。
支持的配置有:
minSdkVersion 最小支持sdk版本
targetSdkVersion 編譯時的目標sdk版本
versionCode 程序版本號
versionName 程序版本名稱
packageName 程序包名
Package Name for the test application 測試用的程序包名
Instrumentation test runner 測試用的instrumentation實例
例如:
android { compileSdkVersion 19 buildToolsVersion "19.0.0" defaultConfig { versionCode 12 versionName "2.0" minSdkVersion 16 targetSdkVersion 16 } }
默認狀況下項目目錄是這樣的 有兩個組件source sets,一個main,一個test,對應下面兩個文件夾。 src/main/ src/androidTest/
而後對於每一個組件目錄都有兩個目錄,分別存儲java代碼和資源文件 java/ resources/
對於android項目中呢,對應的目錄和文件是 AndroidManifest.xml //該文件src/androidTest/目錄下不須要,程序執行時會自動構建 res/ assets/ aidl/ rs/ jni/
若是須要上面這些文件,可是不是在上面所說的目錄,則須要設置。
sourceSets { main { java { srcDir 'src/java' } resources { srcDir 'src/resources' } } }
能夠給main或者test設置根目錄,如
sourceSets { androidTest.setRoot('tests') }
能夠指定每種文件的存儲路徑
sourceSets { main { manifest.srcFile 'AndroidManifest.xml' java.srcDirs = ['src'] resources.srcDirs = ['src'] aidl.srcDirs = ['src'] renderscript.srcDirs = ['src'] res.srcDirs = ['res'] assets.srcDirs = ['assets'] } }
特別是咱們的ndk生成的.so文件,一般咱們不是放到jni目錄中的,咱們須要設置一下
sourceSets { main { jniLibs.srcDirs = ['libs'] } }
能夠給不一樣類型進行不一樣的配置,先看示例:
android { signingConfigs { debug { storeFile file("debug.keystore") } myConfig { storeFile file("other.keystore") storePassword "android" keyAlias "androiddebugkey" keyPassword "android" } } buildTypes { foo { debuggable true jniDebugBuild true signingConfig signingConfigs.myConfig } } }
上面的配置文件配置兩個類型,一個時debug類型,一個時本身的自定義類型。兩個分別使用了不一樣的簽名,同時對於生成密鑰,要填寫設置的密碼。
直接看代碼:
android { buildTypes { release { runProguard true proguardFile getDefaultProguardFile('proguard-android.txt') } } }
以上是使用默認的proguard文件去進行混淆,也可使用本身編寫的規則進行混淆,proguardFile 'some-other-rules.txt'
程序中會依賴別的包,或者程序,須要引入別的類庫。前面也說到了,支持maven。 對於本地的類庫,能夠這樣引入:
dependencies { compile files('libs/foo.jar') //單個文件 compile fileTree(dir: 'libs', include: ['*.jar']) //多個文件 } android { ... }
對於maven倉庫文件:
repositories { mavenCentral() } dependencies { compile 'com.google.guava:guava:11.0.2' } android { ... }
看代碼:
android { ... defaultConfig { minSdkVersion 8 versionCode 10 } productFlavors { flavor1 { packageName "com.example.flavor1" versionCode 20 } flavor2 { packageName "com.example.flavor2" minSdkVersion 14 } } }
經過以上設置,咱們能夠輸出不一樣的保命不一樣的版本號,以及最小sdk的程序包。固然咱們能夠根據本身的需求去作其餘的不一樣
個人完整配置文件
buildscript { repositories { mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:0.9.+' } } apply plugin: 'android' repositories { mavenCentral() } android { compileSdkVersion 19 buildToolsVersion "19.0.3" defaultConfig { minSdkVersion 8 targetSdkVersion 19 versionCode 1 versionName "1.0" } sourceSets { main { jniLibs.srcDirs = ['libs'] } } lintOptions { abortOnError false } //簽名 signingConfigs { //你本身的keystore信息 release { storeFile file("×.keystore") storePassword "×××" keyAlias "××××" keyPassword "×××" } } buildTypes { debug { signingConfig signingConfigs.release } release { signingConfig signingConfigs.release runProguard false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' } } //渠道Flavors,我這裏寫了一些經常使用的,大家本身改 productFlavors { //GooglePlay{} //Store360{} //QQ{} //Taobao{} //WanDouJia{} //AnZhuo{} //AnZhi{} //BaiDu{} //Store163{} //GFeng{} //AppChina{} //EoeMarket{} //Store91{} //NDuo{} xiaomi{} umeng{} } } //替換AndroidManifest.xml的UMENG_CHANNEL_VALUE字符串爲渠道名稱 android.applicationVariants.all{ variant -> variant.processManifest.doLast{ //以前這裏用的copy{},我換成了文件操做,這樣能夠在v1.11版本正常運行,並保持文件夾整潔 //${buildDir}是指./build文件夾 //${variant.dirName}是flavor/buildtype,例如GooglePlay/release,運行時會自動生成 //下面的路徑是相似這樣:./build/manifests/GooglePlay/release/AndroidManifest.xml def manifestFile = "${buildDir}/manifests/${variant.dirName}/AndroidManifest.xml" //將字符串UMENG_CHANNEL_VALUE替換成flavor的名字 def updatedContent = new File(manifestFile).getText('UTF-8').replaceAll("UMENG_CHANNEL_VALUE", "${variant.productFlavors[0].name}") new File(manifestFile).write(updatedContent, 'UTF-8') //將這次flavor的AndroidManifest.xml文件指定爲咱們修改過的這個文件 variant.processResources.manifestFile = file("${buildDir}/manifests/${variant.dirName}/AndroidManifest.xml") } }
以上的功能就是替換個人Manifest中的umeng渠道標示,同時去生成不一樣的apk包。
程序在buid的時候,會執行lint檢查,有任何的錯誤或者警告提示,都會終止構建,咱們能夠將其關掉。
lintOptions { abortOnError false }
本人使用gradle確實方便不少,雖然電腦配置低,build的時候比較慢。
內容呢,主要時參考谷歌官方的文檔。
關於怎麼安裝,沒有講到,能夠參考這篇文章:http://stormzhang.github.io/android/2014/02/28/android-gradle/
附上我參考的文檔,沒看懂的能夠去看看。http://tools.android.com/tech-docs/new-build-system/user-guide