Gradle Android最新自動化編譯腳本教程

 轉自:http://blog.csdn.net/changemyself/article/details/39927381html

1、前言

Gradle 是以 Groovy 語言爲基礎,面向Java應用爲主。基於DSL(領域特定語言)語法的自動化構建工具。java

上面這句話我以爲寫得很官方,你們只需知道Gradle能夠用來android開發中進行多個項目依賴的自動化編譯腳本,知道這點也就知道咱們使用它的目的;android

爲何不使用Ant作自動化編譯腳本,由於ant上手快,可是維護起來太不方便了,有了Gradle你能夠跟項目組的同事說,用Ant的孩子們別苦逼的維護了,趕忙換成gradle吧。windows

 

本文面向gradle新手或者之前使用過gradle低版本的朋友,由於我感受每次gradle升級那個腳本也有些坑爹,有些api就廢棄掉了,不過整體感受每次升級都讓這個工具更加嚴謹話,易用話了。api

 

2、Demo描述

下面我就簡單寫一個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的編譯,你們自行查資料。

 

3、編譯執行:

下面咱們打開cmd命令窗口進行編譯操做

 

在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致使的。

 

最後囉嗦

今天先寫到這,咱們實際運用中有不少需求,例如:自動根據多渠道打包,根據不一樣的資源和不一樣的pkg進行apk打包,gradle都能幫你搞定,這塊demo後續有時間我貼上來。
有什麼問題,你們能夠跟我交流(QQ羣: 221057495)。

 

4、參考資料:

 

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教程(多評論哈)

相關文章
相關標籤/搜索