新項目中,使用了Google I/O 2013發布的新工具,使用Gradle構建android項目,並且在新版的Intellig IDEA以及google的Android Studio對其支援。本文就介紹一下怎麼使用gradle構建android項目,進行多個版本編譯。
Gradle是什嗎?
Gradle是以Groovy為基礎,面向java應用,基於DSL文法的自動化構建工具。是google引入,替換ant和maven的新工具,其依賴相容maven和ivy。
使用gradle的目的:
更容易重用資源和代碼;
可以更容易建立不同的版本的程式,多個類型的apk包;
更容易配置,擴充;
更好的IDE整合;
環境需求
Gradle1.10或者更高版本,grale外掛程式0.9或者更高版本.
android SDK需要有Build Tools 19.0.0以及更高版本
Gradle基本結構
使用ide建立的gradle構建的項目,會自動建立一個build.gradle,如下:
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項目的參數
任務task的執行
通常會有以下任務:
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的程式包。當然我們可以根據自己的需求去做其他的不同
產生多個渠道包(以Umeng為例)
我的完整設定檔
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 }
最後PS一下
本人使用gradle確實方便很多,雖然電腦配置低,build的時候比較慢。
內容呢,主要時參考Google官方的文檔。
關於怎麼安裝,沒有講到,可以參考這篇文章:http://stormzhang.github.io/android/2014/02/28/android-gradle/
附上我參考的文檔,沒看懂的可以去看看。http://tools.android.com/tech-docs/new-build-system/user-guide
原文地址:http://blog.isming.me/blog/2014/05/20/android4gradle/,歡迎轉載,轉載請註明出處。