轉自:http://blog.csdn.net/changemyself/article/details/39927381html
Gradle 是以 Groovy 語言爲基礎,面向Java應用爲主。基於DSL(領域特定語言)語法的自動化構建工具。java
上面這句話我以爲寫得很官方,你們只需知道Gradle能夠用來android開發中進行多個項目依賴的自動化編譯腳本,知道這點也就知道咱們使用它的目的;android
爲何不使用Ant作自動化編譯腳本,由於ant上手快,可是維護起來太不方便了,有了Gradle你能夠跟項目組的同事說,用Ant的孩子們別苦逼的維護了,趕忙換成gradle吧。windows
本文面向gradle新手或者之前使用過gradle低版本的朋友,由於我感受每次gradle升級那個腳本也有些坑爹,有些api就廢棄掉了,不過整體感受每次升級都讓這個工具更加嚴謹話,易用話了。api
下面我就簡單寫一個demo,經過這個demo程序讓你們如何快速上手,比較實用的一個實例:app
demo程序分爲2個工程,你能夠直接實用eclipse新建一個android工程,其實我也是這麼幹的,這樣一來你們仔細看下圖eclipse
這裏順便強調一下demo工程的環境配置:(很重要,不然下面被我坑了別怪我提起沒跟你說)maven
jdk:C:\Program Files\Java\jdk1.8.0_20(注意:不要使用jre,gradle會提示你使用jdk的)工具
不然腳本會提示如下錯誤:gradle
* What went wrong: Execution failed for task ':appcompat_v7:compileReleaseJava'. > Cannot find System Java Compiler. Ensure that you have installed a JDK (not just a JRE) and configured your JAVA_HOME system variable to point to the according directory.
android-sdk:D:\dev\adt-bundle-windows-x86-20140702
android-api: 20, android4.4W(注意:作android開發你每次都是用最新的api編譯是一個好習慣)
gradle:2.1,(使用最新的版本,no zuo no die,被坑不斷,歡樂不斷)
gradle的下載地址:http://www.gradle.org/documentation ,你們能夠看看文檔,固然你的E文好的話,會容易上手,不過不要緊,看了我寫的文章你gradle的文檔你能夠不看了,由於不少東西你用不上,除非你項目中使用了特別複雜的功能
gradle2.1的api文檔:http://www.gradle.org/docs/current/javadoc/org/gradle/api/Project.html ,這個須要你偶爾翻翻,由於簡單功能會用上的
環境變量配置:
JAVA_HOME,GRADLE_HOME都要添加到環境變量裏
固然了path變量裏你也要加上 JAVA_HOME/bin,和GRADLE_HOME/bin,這樣下面你開一個CMD命令行,才能夠方面使用gradle build命令
好了準備工做完成後,咱們就開始正式講講這個demo工程了
TestDemo工程就寫了一個activity,顯示hello world!
Appcompatv7工程你們懂得一個library,頗有表明性,咱們實際項目中會用到多個library,你能夠觸類旁通了。
下面看看目錄文件:
你想運行編譯腳本,須要2個配置文件,local.properties和settings.gradle
settings.gradle裏的代碼內容:
include ':appcompat_v7', ':TestDemo'
這裏面能夠看到是project的描述,若是你有多個工程如論主工程仍是引用的庫工程,都須要在這裏面聲明,不然gradle找不到
local.properties裏的代碼內容:
sdk.dir=D:\\dev\\adt-bundle-windows-x86-20140702\\sdk
這裏面能夠看到是android sdk的目錄,本身填好,不然也會報錯。
好了下面講講每一個工程裏面都須要配置一個build.gradle 文件
appcompat_v7工程的build.gradle:
buildscript{ repositories{ mavenCentral(); } dependencies{ classpath 'com.android.tools.build:gradle:0.13.+' } tasks.withType(JavaCompile) { options.encoding = "UTF-8" } } apply plugin:'android-library' dependencies{ compile fileTree(dir:'libs',include:"*.jar") } android{ compileSdkVersion 20 buildToolsVersion "20" enforceUniquePackageName=false lintOptions{ abortOnError false } sourceSets{ main{ manifest.srcFile 'AndroidManifest.xml' java.srcDirs = ['src'] resources.srcDirs = ['src'] aidl.srcDirs = ['src'] renderscript.srcDirs = ['src'] res.srcDirs = ['res'] assets.srcDirs = ['assets'] } } lintOptions{ abortOnError false } }
對於這個文件我須要強調幾點:
一、classpath 'com.android.tools.build:gradle:0.13.+' ,不少人用了低版本出了問題寫什麼0.11+,我無論,你要使用gradle2.1版本,這裏就寫成1.13+包你沒錯。
二、apply plugin:'android-library',說明這個一個庫工程,詳細本身找資料腦補
三、tasks.withType(JavaCompile) { options.encoding = "UTF-8" } ,task是個啥本身查去,這裏編譯encoding配成UTF-8,還有一點在低版本腳本有的人寫成tasks.withType(Compile) ,這樣子報錯了,改爲JavaCompile吧,我是一點一點排錯的
四、android{
compileSdkVersion 20
buildToolsVersion "20"
這裏面version寫20,爲啥?上面你看看個人android-sdk api的版本就知道了,寫成別的也能夠,你要保證你本地androidsdk都有。
TestDemo工程裏的幾個文件:
build目錄:是gradle執行編譯時候生成的,裏面好多內容,有興趣本身翻翻看
output目錄:我寫得腳本,最後把build裏的apk自動copy到這個目錄,這個能夠具體看腳本
blue_key:apk簽名文件
build.gradle:你懂得
TestDemo工程裏面的build.gradle
import java.util.regex.Pattern //import com.android.builder.DefaultManifestParser import com.android.builder.core.DefaultManifestParser buildscript{ repositories{ mavenCentral() } dependencies{ classpath 'com.android.tools.build:gradle:0.13.+' } /*** tasks.withType(Compile){ options.encoding = "UTF-8" } **/ tasks.withType(JavaCompile) { options.encoding = "UTF-8" } } apply plugin:'android' dependencies{ compile fileTree(dir:"libs",include:'*.jar') compile project(':appcompat_v7') } android{ compileSdkVersion 20 buildToolsVersion "20" enforceUniquePackageName=false defaultConfig{ targetSdkVersion 17; } lintOptions{ abortOnError false } dexOptions { preDexLibraries = false } packagingOptions { exclude 'META-INF/DEPENDENCIES.txt' exclude 'META-INF/LICENSE.txt' exclude 'META-INF/NOTICE.txt' exclude 'META-INF/NOTICE' exclude 'META-INF/LICENSE' exclude 'META-INF/DEPENDENCIES' exclude 'META-INF/notice.txt' exclude 'META-INF/license.txt' exclude 'META-INF/dependencies.txt' exclude 'META-INF/LGPL2.1' exclude 'META-INF/ASL2.0' } signingConfigs{ myConfig{ storeFile file("bluekey") storePassword "blue" keyAlias "blue" keyPassword "blue" } } buildTypes{ release{ runProguard true //打開混淆開關 proguardFile 'proguard.txt.txt' //配置單個文件這樣 signingConfigs.myConfig } } sourceSets{ main{ manifest.srcFile 'AndroidManifest.xml' java.srcDirs = ['src'] resources.srcDirs = ['src'] aidl.srcDirs = ['src'] //rendersrcDirs = ['src'] res.srcDirs = ['res'] assets.srcDirs = ['assets'] } } task copyNativeLibs(type: Copy) { from(new File(project(':appcompat_v7').getProjectDir(), 'libs')) { include '**/*.so' } into new File(buildDir, 'native-libs') } tasks.withType(JavaCompile){ compileTask -> compileTask.dependsOn copyNativeLibs } clean.dependsOn 'cleanCopyNativeLibs' tasks.withType( com.android.build.gradle.tasks.PackageApplication){ pkgTask -> pkgTask.jniFolders = new HashSet<File>() pkgTask.jniFolders.add(new File(buildDir,'native-libs')) } } build.doLast { def today = new Date().format('yyMMdd'); copy{ //from('build/apk') from('build/outputs/apk') into('output') include('TestDemo-debug.apk') rename('TestDemo-debug.apk','blue-'+today+'-'+readVersion()+'-demo.apk') } } /** *從Manifest.xml中讀取版本號 **/ def readVersion(){ def manifestParser = new DefaultManifestParser() return manifestParser.getVersionName(android.sourceSets.main.manifest.srcFile); }
對於這個文件我須要強調幾點(很重要):
一、//import com.android.builder.DefaultManifestParser
import com.android.builder.core.DefaultManifestParser
//註釋掉的代碼是低版本的寫法,目前使用最新api
二、 /***
tasks.withType(Compile){
options.encoding = "UTF-8"
}
**/
tasks.withType(JavaCompile) { options.encoding = "UTF-8" }
//註釋掉的代碼是低版本的寫法,目前使用最新api
三、
dependencies{
compile fileTree(dir:"libs",include:'*.jar')
compile project(':appcompat_v7')
}
編譯依賴,咱們能夠看到依賴的庫 appcompat_v7要寫在這裏,注意":"(冒號必定要寫)
四、
signingConfigs{
myConfig{
storeFile file("bluekey")
storePassword "blue"
keyAlias "blue"
keyPassword "blue"
}
}
buildTypes{
release{
signingConfigs.myConfig
}
}
編譯時候簽名文件配置,固然你也能夠編譯出debug和沒有簽名的apk,自行查資料去
五、
task copyNativeLibs(type: Copy) {
from(new File(project(':appcompat_v7').getProjectDir(), 'libs')) { include '**/*.so' }
into new File(buildDir, 'native-libs')
}
tasks.withType(JavaCompile){
compileTask -> compileTask.dependsOn copyNativeLibs
}
關於依賴的so文件和jar文件,在編譯以前copy依賴到主工程的native-libs目錄
六、build.doLast {
def today = new Date().format('yyMMdd');
copy{
//from('build/apk')
from('build/outputs/apk')
into('output')
include('TestDemo-debug.apk')
rename('TestDemo-debug.apk','blue-'+today+'-'+readVersion()+'-demo.apk')
}
}
/**
*從Manifest.xml中讀取版本號
**/
def readVersion(){
def manifestParser = new DefaultManifestParser()
return manifestParser.getVersionName(android.sourceSets.main.manifest.srcFile);
}
build.doLast,就是最後執行的意思,關於gradle task你們須要簡單查資料掌握便可。
這裏面須要注意的:
def today = new Date().format('yyMMdd');
def manifestParser = new DefaultManifestParser()
都須要def聲明變量,低版本不用寫的,可是目前不寫就要報錯了。
這個代碼的功能:就是從Manifest文件裏讀出versioncode而後結合當前日期從新命名output裏的apk文件。
方便吧,很實用的一點。
七、apply plugin:'android'
這說明這個腳本須要編譯的是一個 android工程,跟上面的library是否是有所不一樣呢? gradle還支持java project的編譯,你們自行查資料。
在TestDemo目錄執行gradle build,由於這裏是local.properties和settings.gradle 所在的根目錄。
第一次執行時候,gradle根據依賴去下載所須要的jar包,會在你每一個工程裏建立一個.gradle目錄
dependencies{
classpath 'com.android.tools.build:gradle:0.13.+'
}
下載成功後
ok,那咱們開始執行編譯操做了,gradle build
編譯正常的話會提示 BUILD SUCCESSFUL,而後本身去output目錄找apk去。
這裏提醒你們一個jar衝突會引發編譯中斷的問題:
由於不少朋友的project的libs目錄有多個android-support-v4.jar致使的。
最後囉嗦
After upgrading to Gradle 2.0: Could not find property 'Compile' on root project
Unable to resolve class in build.gradle using Android Studio 0.60/Gradle 0.11
How to configure build.gradle files of an existing project with actionbarsherlock lib?
Multiple settings gradle files for multiple projects building
Android Tools Project Site
demo下載地址:
gradle2.1demo教程(多評論哈)