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

本文介绍了Gradle作为自动化构建工具在Android开发中的优势,并详细讲解了环境配置、版本选择、Gradle脚本的关键点,包括依赖配置、签名设置、SO文件处理、版本号读取以及编译执行过程。通过实例演示如何解决编译过程中的问题,如依赖冲突和API更新。最后,指导读者进行编译操作并解析apk命名规则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、前言

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

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

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

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


二、环境变量配置

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:你懂得


四、Demo工程里面的build.gradle

[html]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. import java.util.regex.Pattern  
  2. //import com.android.builder.DefaultManifestParser  
  3. import com.android.builder.core.DefaultManifestParser  
  4.   
  5.   
  6. buildscript{  
  7.     repositories{  
  8.         mavenCentral()  
  9.     }  
  10.     dependencies{  
  11.         classpath 'com.android.tools.build:gradle:0.13.+'  
  12.   
  13.     }  
  14.   
  15.     /***  
  16.     tasks.withType(Compile){  
  17.         options.encoding = "UTF-8"  
  18.     }  
  19.     **/  
  20.   
  21.     tasks.withType(JavaCompile) { options.encoding = "UTF-8" }  
  22. }  
  23.   
  24. apply plugin:'android'  
  25.   
  26. dependencies{  
  27.     compile fileTree(dir:"libs",include:'*.jar')  
  28.     compile project(':appcompat_v7')  
  29. }  
  30.   
  31. android{  
  32.     compileSdkVersion 20  
  33.     buildToolsVersion "20"  
  34.     enforceUniquePackageName=false  
  35.       
  36.     defaultConfig{  
  37.         targetSdkVersion 17;  
  38.     }  
  39.       
  40.     lintOptions{  
  41.         abortOnError false  
  42.     }  
  43.   
  44.     dexOptions {  
  45.         preDexLibraries = false  
  46.     }  
  47.   
  48.     packagingOptions {  
  49.         exclude 'META-INF/DEPENDENCIES.txt'  
  50.         exclude 'META-INF/LICENSE.txt'  
  51.         exclude 'META-INF/NOTICE.txt'  
  52.         exclude 'META-INF/NOTICE'  
  53.         exclude 'META-INF/LICENSE'  
  54.         exclude 'META-INF/DEPENDENCIES'  
  55.         exclude 'META-INF/notice.txt'  
  56.         exclude 'META-INF/license.txt'  
  57.         exclude 'META-INF/dependencies.txt'  
  58.         exclude 'META-INF/LGPL2.1'  
  59.         exclude 'META-INF/ASL2.0'  
  60.     }  
  61.   
  62.     signingConfigs{  
  63.         myConfig{  
  64.             storeFile file("bluekey")  
  65.             storePassword "blue"  
  66.             keyAlias "blue"  
  67.             keyPassword "blue"  
  68.         }  
  69.     }  
  70.   
  71.     buildTypes{  
  72.         release{  
  73.               
  74.   
  75.             runProguard true  //打开混淆开关  
  76.             proguardFile 'proguard.txt.txt'  //配置单个文件这样  
  77.   
  78.             signingConfigs.myConfig  
  79.         }  
  80.     }  
  81.   
  82.     sourceSets{  
  83.         main{  
  84.             manifest.srcFile 'AndroidManifest.xml'  
  85.             java.srcDirs = ['src']  
  86.             resources.srcDirs = ['src']  
  87.             aidl.srcDirs = ['src']  
  88.             //rendersrcDirs = ['src']  
  89.             res.srcDirs = ['res']  
  90.             assets.srcDirs = ['assets']  
  91.         }  
  92.     }  
  93.   
  94.     task copyNativeLibs(type: Copy) {  
  95.         from(new File(project(':appcompat_v7').getProjectDir(), 'libs')) { include '**/*.so' }  
  96.         into new File(buildDir, 'native-libs')  
  97.     }  
  98.   
  99.       
  100.     tasks.withType(JavaCompile){  
  101.         compileTask -> compileTask.dependsOn copyNativeLibs  
  102.     }  
  103.   
  104.     clean.dependsOn 'cleanCopyNativeLibs'  
  105.   
  106.     tasks.withType( com.android.build.gradle.tasks.PackageApplication){  
  107.         pkgTask -> pkgTask.jniFolders = new HashSet<File>()  
  108.         pkgTask.jniFolders.add(new File(buildDir,'native-libs'))  
  109.     }  
  110.       
  111.       
  112.       
  113. }  
  114.   
  115. build.doLast {  
  116.         def today = new Date().format('yyMMdd');  
  117.         copy{  
  118.             //from('build/apk')  
  119.             from('build/outputs/apk')  
  120.             into('output')  
  121.             include('TestDemo-debug.apk')  
  122.             rename('TestDemo-debug.apk','blue-'+today+'-'+readVersion()+'-demo.apk')  
  123.         }  
  124. }  
  125.       
  126. /**  
  127.     *从Manifest.xml中读取版本号  
  128.     **/  
  129.     def readVersion(){  
  130.         def manifestParser = new DefaultManifestParser()  
  131.         return manifestParser.getVersionName(android.sourceSets.main.manifest.srcFile);  
  132.     }  

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

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后续有时间我贴上来。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值