您的位置:首页 > 其它

最新自动化编译脚本,关于gradle编译遇到的一些问题的解决方案

2014-11-05 13:16 701 查看


一、前言

Gradle 是以 Groovy 语言为基础,面向Java应用为主。基于DSL(领域特定语言)语法的自动化构建工具。

上面这句话我觉得写得很官方,大家只需知道Gradle可以用来android开发中进行多个项目依赖的自动化编译脚本,知道这点也就知道我们使用它的目的;

为什么不使用Ant做自动化编译脚本,因为ant上手快,但是维护起来太不方便了,有了Gradle你可以跟项目组的同事说,用Ant的孩子们别苦逼的维护了,赶紧换成gradle吧。

本文面向gradle新手或者以前使用过gradle低版本的朋友,因为我感觉每次gradle升级那个脚本也有些坑爹,有些api就废弃掉了,不过总体感觉每次升级都让这个工具更加严谨话,易用话了。

二、[b]环境变量配置:[/b]

JAVA_HOME,GRADLE_HOME都要添加到环境变量里

当然了path变量里你也要加上 JAVA_HOME/bin,和GRADLE_HOME/bin,这样下面你开一个CMD命令行,才可以方面使用gradle build命令

三、版本配置

android-sdk:D:\dev\adt-bundle-windows-x86-20140702

android-api: 20, android4.4W(注意:做android开发你每次都是用最新的api编译是一个好习惯)

gradle:2.1,(使用最新的版本)

gradle2.1的api文档:http://www.gradle.org/docs/current/javadoc/org/gradle/api/Project.html ,这个需要你偶尔翻翻,因为简单功能会用上的

三、demo说明

Demo工程里的几个文件:



build目录:是gradle执行编译时候生成的,里面好多内容,有兴趣自己翻翻看

output目录:我写得脚本,最后把build里的apk自动copy到这个目录,这个可以具体看脚本

blue_key:apk签名文件

build.gradle:你懂得

[b]四、Demo工程里面的build.gradle[/b]

[html] view
plaincopyprint?





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);

}

对于这个文件我需要强调几点(很重要):

1、

//import com.android.builder.DefaultManifestParser

import com.android.builder.core.DefaultManifestParser //注释掉的代码是低版本的写法,目前使用最新api

2、

/***

tasks.withType(Compile){ options.encoding = "UTF-8" }

**/

tasks.withType(JavaCompile) { options.encoding = "UTF-8" }

//注释掉的代码是低版本的写法,目前使用最新api

3、

dependencies{

compile fileTree(dir:"libs",include:'*.jar')

compile project(':appcompat_v7')

}

编译依赖,我们可以看到依赖的库 appcompat_v7要写在这里,注意":"(冒号一定要写)

4、

signingConfigs{

myConfig{

storeFile file("bluekey")

storePassword "blue"

keyAlias "blue"

keyPassword "blue"

}

}

buildTypes{

release{

signingConfigs.myConfig

}

}

编译时候签名文件配置,当然你也可以编译出debug和没有签名的apk,自行查资料去

5、

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目录

6、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文件。



方便吧,很实用的一点。

7、apply plugin:'android'

这说明这个脚本需要编译的是一个 android工程,跟上面的library是不是有所不同呢? gradle还支持java project的编译,大家自行查资料。


三、编译执行:


下面我们打开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后续有时间我贴上来。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: