Gradle系列第(三)篇---Android Studio与Gradle那些事儿
2016-12-14 16:42
519 查看
·
本来这篇要写Android性能优化的,个人时间比较少,每天加班到很晚,写博客的时间就很少了,但是Gradle系列的文章还没有写完,所以补一篇,在Gradle系列第(二)篇—Gradle编程主要对象主要写了Gradle中的几个对象(Project,Settings,Gradle,Task、Action),现在聊一聊Android Studio中的gradle常见的功能需求。如果你還沒有阅读过我的前两篇博客Gradle系列第(一)篇—Groovy语法初探和Gradle系列2—Gradle编程主要对象,可以先看一下,有助于本文的理解,好啦,各位看官准备好瓜子花生,接下来一大篇文章哗啦啦的来了。不过不用担心,这篇博客仍然是面向基础。
读完这篇博客,你会了解到这些内容
- 1、Android的构建文件
- 2、全局参数配置
- 3、用脚本更改项目结构
- 4、多种apk的生成
- 5、签名的配置与使用
- 6、项目混淆(Proguard)
- 7、gradle多渠道打包
- 8、APK需求定制的案例
- 9、动态参数配置
- 10、gradle依赖管理
- 11、gradle.properties文件配置
- 12、jar文件输出
一、AS项目构建文件的简单解释
一个AS项目结构大概像下面这样子
如蓝色条所示,项目中总共包含了6个构建文件(不算Library中的gradle),我们先从宏观的方面了解一下,每个构建文件的作用是啥?
1、这个文件是app文件夹下这个Module的gradle配置文件,也可以算是整个项目最主要的gradle配置文件,比如自动打包debug,release,beta等环境,签名,多渠道打包,混淆等操作都可以在这里面写。每一个Module都需要有一个gradle配置文件。
2、我们主要看下gradle-wrapper.properties这个文件的内容
可以看到里面声明了gradle的目录与下载路径以及当前项目使用的gradle版本,这些默认的路径我们一般不会更改的,有時候导入一个新项目,gradle版本不对,可以在这里修改。
3、这个文件是整个项目的gradle基础(全局)配置文件,内容主要包含了两个方面:一个是声明仓库的源,这里可以看到是指明的jcenter(), 之前版本则是mavenCentral(), jcenter可以理解成是一个新的中央远程仓库,兼容maven中心仓库,而且性能更优。另一个是声明了android gradle plugin的版本。allprojects:中定义的属性会被应用到所有 moudle 中,但是为了保证每个项目的独立性,我们一般不会在这里面操作太多共有的东西。
所有通过gradle导入的jar包都是从http://bintray.com/bintray/jcenter这个中央仓库上扒下来的。如果你需要的jar包在这个网站上没有,那就无法通过gradle的方式来导入哦。
4、这个里面可以配置参数,然后在其他build.gradle中引用,后面会讲例子,如何动态配置参数。
5、这里主要指定了ndk和SDK的路径
6、setting.gradle最关键的内容就是告诉Gradle这个multiprojects包含哪些子projects,当你的app只有一个模块的时候,你的setting.gradle将会是这样子的:
当你的app有多个模块的时候,你的setting.gradle将会是这样子的
setting.gradle文件将会在gradle初始化时期执行,关于初始化时期,可以查看上一篇博客,并且定义了哪一个模块将会被构建。举个例子,上述setting.gradle包含了app模块,setting.gradle是针对多模块操作的,所以单独的模块工程完全可以删除掉该文件。在这之后,Gradle会为我们创建一个Setting对象,每一个settings.gradle都会转换成一个Settings对象,并为其包含必要的方法,你不必知道Settings类的详细细节,但是你最好能够知道这个概念。另外可以在settings做一些初始化的工作,后面介绍。
读到这里做个总结
- build.gradle:控制每个Module的构建过程
- gradle.properties:设置gradle脚本中的参数
- local.properties:gradle的SDK和NDK环境变量配置
- gradle.properties:用于配置参数信息
- setting.gradle :配置gradle的多项目管理
二、实用技能精讲
1、全局参数配置
通常我们的项目都有很多的Module,像我现在公司的项目就有十几个,那么每个Module里面的gradle文件通常都有类似这样的配置。
这些配置对于每个Module来说,最好统一,我把它定义在项目根目录的gradle文件中,如下。
定义好了,我们可以在各个Module的gradle文件文件中引用,如下:
利用Gradle全局变量,对于多Module有很大的好处,方便统一,除了上面的列子,在举个例子。上面全部按照单个的属性配置的,对于相关的属性,可以将他们写到一个列表中,下面定义了一个dependencies_config的列表。
在Module中,这样引用
2、项目结构更改
sourceSets 的作用是重新定义资源文件位置,比如
在你Sync Now之后,会出现activity和fragment两个文件夹
最常见的是下面这块代码,当Eclipse项目转到Studio的时候,需要重新指定一些文件的位置。
sourceSets的用法就是这样,可以重新指定文件目录,但是读到这,可能有些人心中有个问题,为什么sourceSets ,defaultConfig这样的东东要写在android的大括号中。换言之,android这个大括号里面还能写什么东西,我来列举一下。
在DSL文档中,以上每个类型都有它的详细配置选项,一般常见的设置就是上面啦,如果你觉得有的不太了解,看下面之后就了解了。
3、多种apk的生成
默认studio生成的buildTypes是像下面这样的,但是呢,我还想要其他的变种类型。
我们可以这样添加
通过这样就可以得到多种变种app,执行assemble这个task,打出所有apk。
总共得到系统默认有的release和debug两个apk,额外还有r1,r2,r3三个不同的apk。
那么applicationIdSuffix是什么呢,逆向r1包看看。
系统通过包名来区分应用,这种方式无非就是在包名后面加上了一个后缀r1。
4、签名的配置与使用
上面打出的包都是没有指定签名的,我们要配置一个签名,首先需要生成签名文件。我生成的签名文件是1.jks
签名在signingConfigs中配置,signR1,signR2是签名的名字,在buildTypes中使用。
加上签名后打的包是这样,跟未加签名相比较,多了app-r1.apk,app-r2.apk。
5、项目混淆(Proguard)
面对众多的渠道,打包也有很多不同的需求。 比如 debug版,release版,dev版等等。 有时候不同的版本中使用到的不同的服务端api域名也不相同。 比如 debug_api.com,release_api.com,dev_api.com等等。不同的版本对应了不同的 api 域名,还可能对应不同的 icon 等。渠道首发包通常需要要求在欢迎页添加渠道的logo等。下面我们开始进行打包。首先进行混淆设置,混淆需要buildTypes中配置,在上面说过,默认生成的buildTypes是这样子的
其中,proguard-android.txt是在你的sdk\tools\proguard目录下。minifyEnabled:表示是否开启混淆,默认为false;proguardFiles:混淆配置文件,一般就采用项目中默认的proguard-rules.pro文件。在这个文件中写我们的混淆规则,比如:
有这些还不够,还需要在gradle中开启混淆
我们设置minifyEnabled true,就会在打包的时候进行代码混淆处理. 其中proguard-android.txt不用管,在sdk目录里面,我们主要是配置了proguard.cfg文件。可能大家直接在android studio创建项目不会有这个文件,而是proguard-rules.pro文件,其实一样的,我这里是因为项目是从eclipse迁移过来的,之前在eclipse上混淆是proguard.cfg文件.
6、gradle多渠道打包
1、第一步 在AndroidManifest.xml里配置PlaceHolder
2、第二步 在build.gradle设置productFlavors
或者批量修改
最后,最好在defaultConfig中定义一个默认的渠道
到此配置完成,可以执行命令了。
- 3、去工程的根目录,也就是有gradlew文件的目录,打开命令行,输入命令:
./gradlew assemble
这时候你去app/build/outputs/apk中就能看到自动打好的渠道包了。
./gradlew assembleRelease
只打Release包
./gradlew assembleDebug
只打Debug包
./gradlew assemblebaidu
只打360的渠道包
./gradlew assemblebaiduRelease
不想敲命令行的,调起下面这个面板打包
7、APK需求定制
上面说了一下打包,在打包的時候,一些特殊化的操作,比如修改指定apk Logo,apk重命名,这些怎么搞?
渠道包重命名
根据渠道修改APP名称
其中 resValue(“string”,”app_name”,”DEBUG”) 表示一个string 类型的变量app_name的值是DEBUG,做了上面的配置之后,需要将string.xml的app_name删掉,因为gradle编译的时候,会将脚本中的配置跟string.xml的合并。
8、动态参数配置
上面的这段配置,有个缺点,就是值直接写死了,我们可以动态配置参数。在哪里配置呢,一开始就说了,在gradle.properties中配置参数。如下:
配置好了,就可以“到处”使用了
9、gradle依赖管理
比如我们想依赖个support-v4包,直接一句话:
一个依赖需要定义三个元素:group,name和version。group意味着创建该library的组织名,通常这会是包名,name是该library的唯一标示。
上述的代码是基于groovy语法的,所以其完整的表述应该是这样的:
有些时候,你可能需要和sdk协调工作。为了能顺利编译你的代码,你需要添加SDK到你的编译环境。你不需要将sdk包含在你的APK中,因为它早已经存在于设备中,不需要在compile,我们总共有5个不同的配置:
compile是默认的那个,其含义是包含所有的依赖包,即在APK里,compile的依赖会存在。
apk的意思是apk中存在,但是不会加入编译中,这个貌似用的比较少。
provided的意思是提供编译支持,但是不会写入apk。
testCompile和androidTestCompile会添加额外的library支持针对测试。
通常项目的Module很多,依赖也非常多,为了方便管理,我们应该将这些依赖写到一个全局的地方,可以供其他module使用。这种思想也是第一小节所提的全局参数的配置。依赖管理可以参考:http://stormzhang.com/android/2016/03/13/gradle-config/
10、gradle.properties文件配置
gradle.properties常见配置比如有:
开启并行编译:加快gradle 的编译
org.gradle.parallel=true
开启编译守护进程:该进程在第一次启动后回一直存在,当你进行二次编译的时候,可以重用该进程。
org.gradle.daemon=true
加大可用编译内存:
org.gradle.jvmargs=-Xms256m -Xmx1024m
11、jar文件输出
android Studio常常有输出jar包的需求,只要下面这段代码即可:
OK,Gradle研究了一个多星期,这篇博客耗时两个晚上,终于结束,另外如果时间来的急,在写一篇Gradle系列4或5,因为感觉自己还没有讲清楚,侧重多个Module中gradle的使用与Gradle常用命令的使用,下篇博客继续性能优化系列的更新,每一次写博客都花费很多的时间和精力也是一次锻炼,跟他人分享自己的学习成果,最后附上参考资料,比我写的好。
Gradle for Android : http://www.codeceo.com/article/gradle-for-android-1.html
深入理解Gradle : http://blog.csdn.net/luohai859/article/details/48319129
本来这篇要写Android性能优化的,个人时间比较少,每天加班到很晚,写博客的时间就很少了,但是Gradle系列的文章还没有写完,所以补一篇,在Gradle系列第(二)篇—Gradle编程主要对象主要写了Gradle中的几个对象(Project,Settings,Gradle,Task、Action),现在聊一聊Android Studio中的gradle常见的功能需求。如果你還沒有阅读过我的前两篇博客Gradle系列第(一)篇—Groovy语法初探和Gradle系列2—Gradle编程主要对象,可以先看一下,有助于本文的理解,好啦,各位看官准备好瓜子花生,接下来一大篇文章哗啦啦的来了。不过不用担心,这篇博客仍然是面向基础。
读完这篇博客,你会了解到这些内容
- 1、Android的构建文件
- 2、全局参数配置
- 3、用脚本更改项目结构
- 4、多种apk的生成
- 5、签名的配置与使用
- 6、项目混淆(Proguard)
- 7、gradle多渠道打包
- 8、APK需求定制的案例
- 9、动态参数配置
- 10、gradle依赖管理
- 11、gradle.properties文件配置
- 12、jar文件输出
一、AS项目构建文件的简单解释
一个AS项目结构大概像下面这样子
如蓝色条所示,项目中总共包含了6个构建文件(不算Library中的gradle),我们先从宏观的方面了解一下,每个构建文件的作用是啥?
1、这个文件是app文件夹下这个Module的gradle配置文件,也可以算是整个项目最主要的gradle配置文件,比如自动打包debug,release,beta等环境,签名,多渠道打包,混淆等操作都可以在这里面写。每一个Module都需要有一个gradle配置文件。
2、我们主要看下gradle-wrapper.properties这个文件的内容
#Mon Dec 28 10:00:20 PST 2015 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
可以看到里面声明了gradle的目录与下载路径以及当前项目使用的gradle版本,这些默认的路径我们一般不会更改的,有時候导入一个新项目,gradle版本不对,可以在这里修改。
3、这个文件是整个项目的gradle基础(全局)配置文件,内容主要包含了两个方面:一个是声明仓库的源,这里可以看到是指明的jcenter(), 之前版本则是mavenCentral(), jcenter可以理解成是一个新的中央远程仓库,兼容maven中心仓库,而且性能更优。另一个是声明了android gradle plugin的版本。allprojects:中定义的属性会被应用到所有 moudle 中,但是为了保证每个项目的独立性,我们一般不会在这里面操作太多共有的东西。
buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.2.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } allprojects { repositories { jcenter() } } task clean(type: Delete) { delete rootProject.buildDir }
所有通过gradle导入的jar包都是从http://bintray.com/bintray/jcenter这个中央仓库上扒下来的。如果你需要的jar包在这个网站上没有,那就无法通过gradle的方式来导入哦。
4、这个里面可以配置参数,然后在其他build.gradle中引用,后面会讲例子,如何动态配置参数。
5、这里主要指定了ndk和SDK的路径
ndk.dir=G\:\\Users\\wangjing\\AppData\\Local\\Android\\sdk\\ndk-bundle sdk.dir=G\:\\Users\\wangjing\\AppData\\Local\\Android\\sdk
6、setting.gradle最关键的内容就是告诉Gradle这个multiprojects包含哪些子projects,当你的app只有一个模块的时候,你的setting.gradle将会是这样子的:
include ':app'
当你的app有多个模块的时候,你的setting.gradle将会是这样子的
include ':app', ':library',。。。。
setting.gradle文件将会在gradle初始化时期执行,关于初始化时期,可以查看上一篇博客,并且定义了哪一个模块将会被构建。举个例子,上述setting.gradle包含了app模块,setting.gradle是针对多模块操作的,所以单独的模块工程完全可以删除掉该文件。在这之后,Gradle会为我们创建一个Setting对象,每一个settings.gradle都会转换成一个Settings对象,并为其包含必要的方法,你不必知道Settings类的详细细节,但是你最好能够知道这个概念。另外可以在settings做一些初始化的工作,后面介绍。
读到这里做个总结
- build.gradle:控制每个Module的构建过程
- gradle.properties:设置gradle脚本中的参数
- local.properties:gradle的SDK和NDK环境变量配置
- gradle.properties:用于配置参数信息
- setting.gradle :配置gradle的多项目管理
二、实用技能精讲
1、全局参数配置
通常我们的项目都有很多的Module,像我现在公司的项目就有十几个,那么每个Module里面的gradle文件通常都有类似这样的配置。
android { compileSdkVersion 24 buildToolsVersion "24.0.0" defaultConfig { applicationId "com.zhangwan.www.gradle" minSdkVersion 15 targetSdkVersion 24 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } }
这些配置对于每个Module来说,最好统一,我把它定义在项目根目录的gradle文件中,如下。
//全局配置 ext { minSdkVersion =15 targetSdkVersion =24 compileSdkVersion =24 buildToolsVersion ="24.0.0" versionCode =1 versionName="1.0" }
定义好了,我们可以在各个Module的gradle文件文件中引用,如下:
android { compileSdkVersion rootProject.ext.compileSdkVersion buildToolsVersion rootProject.ext.buildToolsVersion defaultConfig { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion versionCode rootProject.ext.versionCode versionName rootProject.ext.versionName testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } }
利用Gradle全局变量,对于多Module有很大的好处,方便统一,除了上面的列子,在举个例子。上面全部按照单个的属性配置的,对于相关的属性,可以将他们写到一个列表中,下面定义了一个dependencies_config的列表。
ext{ dependencies_config=[supportv7:"com.android.support:appcompat-v7:25.0.0"] }
在Module中,这样引用
dependencies { compile rootProject.ext.dependencies_config.supportv7 ..... }
2、项目结构更改
sourceSets 的作用是重新定义资源文件位置,比如
android { compileSdkVersion 24 buildToolsVersion "24.0.0" sourceSets{ main{ res.srcDirs=['src/main/res','src/main/res/layout/activity','src/main/res/layout/fragment'] } } }
在你Sync Now之后,会出现activity和fragment两个文件夹
最常见的是下面这块代码,当Eclipse项目转到Studio的时候,需要重新指定一些文件的位置。
sourceSets { main { manifest.srcFile 'AndroidManifest.xml' java.srcDirs = ['src'] resources.srcDirs = ['src'] aidl.srcDirs = ['src'] renderscript.srcDirs = ['src'] res.srcDirs = ['res'] assets.srcDirs = ['assets'] jniLibs.srcDirs = ['libs'] } }
sourceSets的用法就是这样,可以重新指定文件目录,但是读到这,可能有些人心中有个问题,为什么sourceSets ,defaultConfig这样的东东要写在android的大括号中。换言之,android这个大括号里面还能写什么东西,我来列举一下。
android { defaultConfig { //默认配置项,defaultConfig就是程序的默认配置,注意,如果在 AndroidMainfest.xml里面定义了与这里相同的属性,会以这里的为主。 } buildTypes { // 编译配置,release或debug版本的内容 } compileOptions { // Java 的版本配置 } sourceSets { //源码设置(项目目录结构的设置) } packagingOptions { //打包时的相关配置 } lintOptions { //编译的 lint 开关,程序在buid的时候,会执行lint检查,有任何的错误或者警告提示,都会终止构建,我们可以将其关掉。 //abortOnError false } productFlavors { //产品发布的一些东西,比如渠道、包名等 flavor1 { } flavor2 { } } signingConfigs { //签名的配置 release { } } testOptions{ //测试配置,TestOptions类型 } aaptOptions{ //aapt配置,AaptOptions类型 } lintOptions{ //lint配置,LintOptions类型 } dexOptions{ //dex配置,DexOptions类型 } compileOptions{ // 编译配置,CompileOptions类型 } packagingOptions{ // PackagingOptions类型 } jacoco{ //JacocoExtension类型。 用于设定 jacoco版本 } splits{ //Splits类型。 } }
在DSL文档中,以上每个类型都有它的详细配置选项,一般常见的设置就是上面啦,如果你觉得有的不太了解,看下面之后就了解了。
3、多种apk的生成
默认studio生成的buildTypes是像下面这样的,但是呢,我还想要其他的变种类型。
buildTypes { release { minifyEnabled false// 不混淆 proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } }
我们可以这样添加
buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } r1{ applicationIdSuffix ".r1" } r2{ applicationIdSuffix ".r2" } r3{ applicationIdSuffix ".r3" } }
通过这样就可以得到多种变种app,执行assemble这个task,打出所有apk。
总共得到系统默认有的release和debug两个apk,额外还有r1,r2,r3三个不同的apk。
那么applicationIdSuffix是什么呢,逆向r1包看看。
系统通过包名来区分应用,这种方式无非就是在包名后面加上了一个后缀r1。
4、签名的配置与使用
上面打出的包都是没有指定签名的,我们要配置一个签名,首先需要生成签名文件。我生成的签名文件是1.jks
signingConfigs{ signR1{ storeFile file("build/1.jks"); storePassword "123456" keyAlias "xxx" keyPassword "123456" } signR2{ storeFile file("build/2.jks"); storePassword "123456" keyAlias "xxx" keyPassword "123456" } }
签名在signingConfigs中配置,signR1,signR2是签名的名字,在buildTypes中使用。
buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } r1{ signingConfig signingConfigs.signR1 applicationIdSuffix ".r1" } r2{ signingConfig signingConfigs.signR2 applicationIdSuffix ".r2" } }
加上签名后打的包是这样,跟未加签名相比较,多了app-r1.apk,app-r2.apk。
5、项目混淆(Proguard)
面对众多的渠道,打包也有很多不同的需求。 比如 debug版,release版,dev版等等。 有时候不同的版本中使用到的不同的服务端api域名也不相同。 比如 debug_api.com,release_api.com,dev_api.com等等。不同的版本对应了不同的 api 域名,还可能对应不同的 icon 等。渠道首发包通常需要要求在欢迎页添加渠道的logo等。下面我们开始进行打包。首先进行混淆设置,混淆需要buildTypes中配置,在上面说过,默认生成的buildTypes是这样子的
buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } }
其中,proguard-android.txt是在你的sdk\tools\proguard目录下。minifyEnabled:表示是否开启混淆,默认为false;proguardFiles:混淆配置文件,一般就采用项目中默认的proguard-rules.pro文件。在这个文件中写我们的混淆规则,比如:
-keepclasseswithmembernames class * { # 保持 native 方法不被混淆 native <methods>; } -keepclassmembers enum * { # 保持枚举 enum 类不被混淆 public static **[] values(); public static ** valueOf(java.lang.String); } -keep class * implements android.os.Parcelable { # 保持 Parcelable 不被混淆 public static final android.os.Parcelable$Creator *; }
有这些还不够,还需要在gradle中开启混淆
buildTypes { release { // 不显示 Log buildConfigField "boolean", "LOG_DEBUG", "false" shrinkResources true signingConfig signingConfigs.release minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard.cfg' } debug { // 显示 Log buildConfigField "boolean", "LOG_DEBUG", "true" signingConfig signingConfigs.debug } }
我们设置minifyEnabled true,就会在打包的时候进行代码混淆处理. 其中proguard-android.txt不用管,在sdk目录里面,我们主要是配置了proguard.cfg文件。可能大家直接在android studio创建项目不会有这个文件,而是proguard-rules.pro文件,其实一样的,我这里是因为项目是从eclipse迁移过来的,之前在eclipse上混淆是proguard.cfg文件.
6、gradle多渠道打包
1、第一步 在AndroidManifest.xml里配置PlaceHolder
<meta-data android:name="MY_CHANNEL" android:value="${MY_CHANNEL}" />
2、第二步 在build.gradle设置productFlavors
productFlavors{ xiaomi { //用gradle修改AndroidManifest.xml中的meta-data元素值 manifestPlaceholders = [MY_CHANNEL: "xiaomi"] } _360 { manifestPlaceholders = [MY_CHANNEL: "_360"] } baidu { manifestPlaceholders = [MY_CHANNEL: "baidu"] } huawei{ manifestPlaceholders = [MY_CHANNEL: "huawei"] } }
或者批量修改
productFlavors{ xiaomi {} _360 {} baidu {} huawei{} } productFlavors.all { flavor -> flavor.manifestPlaceholders = [MY_CHANNEL: name] }
最后,最好在defaultConfig中定义一个默认的渠道
defaultConfig{ manifestPlaceholders = [ MY_CHANNEL:"xiaomi" ] }
到此配置完成,可以执行命令了。
- 3、去工程的根目录,也就是有gradlew文件的目录,打开命令行,输入命令:
./gradlew assemble
这时候你去app/build/outputs/apk中就能看到自动打好的渠道包了。
./gradlew assembleRelease
只打Release包
./gradlew assembleDebug
只打Debug包
./gradlew assemblebaidu
只打360的渠道包
./gradlew assemblebaiduRelease
不想敲命令行的,调起下面这个面板打包
7、APK需求定制
上面说了一下打包,在打包的時候,一些特殊化的操作,比如修改指定apk Logo,apk重命名,这些怎么搞?
渠道包重命名
android.applicationVariants.all { variant -> variant.outputs.each { output -> def outputFile = output.outputFile if (outputFile != null && outputFile.name.endsWith('.apk')) { File outputDirectory = new File(outputFile.parent); def fileName if (variant.buildType.name == "release") { fileName = "wangjing_${variant.productFlavors[0].name}.apk" } else { fileName = "wangjing_${variant.productFlavors[0].name}_beta.apk" } output.outputFile = new File(outputDirectory, fileName) } } }
根据渠道修改APP名称
buildTypes { debug { // 显示Log buildConfigField "boolean", "LOG_DEBUG", "true" //重命名 resValue("string","app_name","DEBUG") versionNameSuffix "-debug" minifyEnabled false zipAlignEnabled false shrinkResources false signingConfig signingConfigs.debug } release { // 不显示Log buildConfigField "boolean", "LOG_DEBUG", "false" //重命名 resValue("string","app_name","DEBUG") //混淆 minifyEnabled true //加载默认混淆配置文件 proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' //签名 signingConfig signingConfigs.release } }
其中 resValue(“string”,”app_name”,”DEBUG”) 表示一个string 类型的变量app_name的值是DEBUG,做了上面的配置之后,需要将string.xml的app_name删掉,因为gradle编译的时候,会将脚本中的配置跟string.xml的合并。
8、动态参数配置
signingConfigs{ release{ storeFile file("build/mykey.jks") storePassword "123456" keyAlias "123456" keyPassword "123456" } }
上面的这段配置,有个缺点,就是值直接写死了,我们可以动态配置参数。在哪里配置呢,一开始就说了,在gradle.properties中配置参数。如下:
systemPro.keyAliasPassword=123456 systemPro.keyAlias=123456 systemPro.keyStorePassword=123456 systemPro.keyStore=mykey.jks
配置好了,就可以“到处”使用了
signingConfigs{ release{ storeFile System.properties["keyStore"] storePassword System.properties["keyStorePassword"] keyAlias System.properties["keyAlias"] keyPassword System.properties["keyAliasPassword"] } debug{ storeFile file("mykey.jks") storePassword "123456" keyAlias"123456" keyPassword "123456" } }
9、gradle依赖管理
比如我们想依赖个support-v4包,直接一句话:
compile 'com.android.support:support-v4:23.1.1'
一个依赖需要定义三个元素:group,name和version。group意味着创建该library的组织名,通常这会是包名,name是该library的唯一标示。
上述的代码是基于groovy语法的,所以其完整的表述应该是这样的:
compile group: 'com.android.support:', name: 'support-v4', version:'23.1.1'
有些时候,你可能需要和sdk协调工作。为了能顺利编译你的代码,你需要添加SDK到你的编译环境。你不需要将sdk包含在你的APK中,因为它早已经存在于设备中,不需要在compile,我们总共有5个不同的配置:
compile是默认的那个,其含义是包含所有的依赖包,即在APK里,compile的依赖会存在。
apk的意思是apk中存在,但是不会加入编译中,这个貌似用的比较少。
provided的意思是提供编译支持,但是不会写入apk。
testCompile和androidTestCompile会添加额外的library支持针对测试。
通常项目的Module很多,依赖也非常多,为了方便管理,我们应该将这些依赖写到一个全局的地方,可以供其他module使用。这种思想也是第一小节所提的全局参数的配置。依赖管理可以参考:http://stormzhang.com/android/2016/03/13/gradle-config/
10、gradle.properties文件配置
gradle.properties常见配置比如有:
开启并行编译:加快gradle 的编译
org.gradle.parallel=true
开启编译守护进程:该进程在第一次启动后回一直存在,当你进行二次编译的时候,可以重用该进程。
org.gradle.daemon=true
加大可用编译内存:
org.gradle.jvmargs=-Xms256m -Xmx1024m
11、jar文件输出
android Studio常常有输出jar包的需求,只要下面这段代码即可:
task makeJar(type: Copy) { delete 'build/libs/my.jar' from('build/intermediates/bundles/release/') into('build/libs/') include('classes.jar') rename ('classes.jar', 'my.jar') }
OK,Gradle研究了一个多星期,这篇博客耗时两个晚上,终于结束,另外如果时间来的急,在写一篇Gradle系列4或5,因为感觉自己还没有讲清楚,侧重多个Module中gradle的使用与Gradle常用命令的使用,下篇博客继续性能优化系列的更新,每一次写博客都花费很多的时间和精力也是一次锻炼,跟他人分享自己的学习成果,最后附上参考资料,比我写的好。
Gradle for Android : http://www.codeceo.com/article/gradle-for-android-1.html
深入理解Gradle : http://blog.csdn.net/luohai859/article/details/48319129
相关文章推荐
- Gradle系列第(三)篇---Android Studio与Gradle那些事儿
- Android Studio系列教程五--Gradle命令详解与导入第三方包
- Android Studio系列教程四--Gradle基础
- Android Studio系列教程六--Gradle多渠道打包
- 史上最详细的Android Studio系列教程五--Gradle命令详解与导入第三方包
- 史上最详细的Android Studio系列教程五--Gradle命令详解与导入第三方包
- Android Studio系列教程四--Gradle基础
- 如何使用Android Studio开发Gradle插件系列教程(一)
- Android Studio系列教程六--Gradle多渠道打包
- Android Studio系列教程五--Gradle命令详解与导入第三方包
- android studio gradle 多渠道打包之完全详解(打包系列教程之四)
- [Android Studio系列(五)] Android Studio手动配置Gradle的方法
- ANDROID STUDIO系列教程四--GRADLE基础
- 史上最详细的Android Studio系列教程四--Gradle基础
- Android Studio系列教程五--Gradle命令详解与导入第三方包
- Android Studio系列教程四--Gradle基础
- Android Studio系列教程五--Gradle命令详解与导入第三方包
- Android Studio系列教程四--Gradle基础
- 史上最详细的Android Studio系列教程四--Gradle基础
- 史上最详细的Android Studio系列教程四--Gradle基础