android studio中gradle运用解析
1.gradle是什么
官方解释是:gradle是一个基于Apache Ant和Apache Maven概念的项目自动化构建工具,它使用的是Groovy的特定领域语言来声明项目设置,而不是传统的XML
个人理解是软件环境部署、构建、打包工具。
2.那么为什么要使用gradle工具呢,其优点在什么地方
代码复用:软件研发讲究复用,复用不仅能够提高工作效率,而且使得代码更易于维护,开发者可以通过继承、组合、函数模块等实现不同程度的代码复用。但不知你有没有想过,软件开发也是一种流程,它不仅仅有写代码,还设计到各种工程管理,包括我们每天的build、clean、签名、打包、、发布等等,有没有想过这种过程,也可以用代码编写出来,这个就是gradle的优点,具体操作,后续会详细介绍
差异管理:做android研发的都知道,Android的碎片化严重,国内有很多android的AppStore、很多手机品牌以及不同尺寸的手机,一般的产品都会针对不同的市场发布不同的包来统计不同渠道的下载量、使用情况等情况,可能会针对不同的品牌、尺寸等做一些相应的调整,这种大量的app打包、发布如果要一个个搞,耗时耗力不说,而且难以维护,而gradle提供了productFlavors和buildTypes,根据这两个可以不同配置,可以批量打包,发布不同版本、类型、代码的app
依赖管理:做软件研发的一定不会陌生jar、library的引用,你可以将jar、library等下载到本地再copy到自己的工程里,这样做在代码迁移,以及代码部署时会很麻烦,会出现版本等不一致或不兼容问题,但是gradle中有一个中央仓库的概念,只要在项目的build.gradle文件中添加如
compile:'com.android.support:design:23.1.1'
其中 com.android.support:design就是要引入的包,而23.1.1是引入包的版 本,如果直接替换成+,那么会自动下载最新的包
- 项目部署 :通过一些插件,可以实现自动将你的输出(.jar,.apk,.aar…)上传到指定仓库,自动部署…
3.gradle基础
在我们使用Android Studio新建工程后,默认会生成两个build.gradle文件,一个位于工程根目录,另一个位于app目录下,如下:
还有另一个文件setting.gradle,其是针对module的全局配置,如果工程中添加了一个moudle,就会在setting.gradle中配置新的module,如下图:
下面,我们仔细介绍一下:
- 根目录下的build.gradle文件
buildscript {
repositories {
//中央仓库
jcenter()
//或者使用指定的本地maven库
maven{
url "file://F:/githubrepo/releases"
}
//或者使用指定的远程maven库
maven{
url "远程库地址"
}
}
dependencies {
classpath 'com.android.tools.build:gradle:1.5.0'
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
其中com.android.tools.build:gradle是android特有的插件,maven仓库地址通过jcenter()获取,当然也可以添加额外的maven仓库地址,如:
maven {
url ‘http://mvnrepo.xxx.com/mvn/repository’
}
- app目录下的build.gradle
//声明构建类型 android
apply plugin: 'com.android.application'
android {//设置编译android项目的参数
signingConfigs {//签名config
sign {
keyAlias 'xx'
keyPassword 'xxx'
storeFile file('xxxxxx')
storePassword 'xxxxx'
}
}
compileSdkVersion 23
buildToolsVersion "23.0.1"
defaultConfig {
applicationId "xxxx"
minSdkVersion 15
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
//构建包、混淆、签名、优化等设置
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.sign
}
debug {
signingConfig signingConfigs.sign
}
}
//渠道包设置
productFlavors{
wandoujia{}
qihu360{}
...
}
}
//依赖包管理,支持远程、本地以及单个包引用
dependencies {
//引入libs下的依赖
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.android.support:design:23.1.1'
//远程依赖
compile 'org.greenrobot:eventbus:3.0.+'
//单文件依赖
compile files('libs/android-support-v4.jar')
}
- 代码混淆及apk优化
混淆:在proguard-rules.pro中加入以下代码,基本可以涵盖所有
-optimizationpasses 5 # 指定代码的压缩级别
-dontusemixedcaseclassnames # 是否使用大小写混合
-dontpreverify # 混淆时是否做预校验
-verbose # 混淆时是否记录日志
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* # 混淆时所采用的算法
-keep public class * extends android.app.Activity # 保持哪些类不被混淆
-keep public class * extends android.app.Application # 保持哪些类不被混淆
-keep public class * extends android.app.Service # 保持哪些类不被混淆
-keep public class * extends android.content.BroadcastReceiver # 保持哪些类不被混淆
-keep public class * extends android.content.ContentProvider # 保持哪些类不被混淆
-keep public class * extends android.app.backup.BackupAgentHelper # 保持哪些类不被混淆
-keep public class * extends android.preference.Preference # 保持哪些类不被混淆
-keep public class com.android.vending.licensing.ILicensingService # 保持哪些类不被混淆
-keepclasseswithmembernames class * { # 保持 native 方法不被混淆
native <methods>;
}
-keepclasseswithmembers class * { # 保持自定义控件类不被混淆
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {# 保持自定义控件类不被混淆
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers class * extends android.app.Activity { # 保持自定义控件类不被混淆
public void *(android.view.View);
}
-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 *;
}
另外,通过 Android Studio进行 混淆代码时,默认已经将 lib目录中的 jar 都已经添加到打包脚本中,所以不需要再次手动添加,否则会出现“ java.io.IOException: The same input jar is specified twice” 错误。
优化:在build.gradle文件中添加如下代码
buildTypes {
release {
//混淆
minifyEnabled true
//Zipalign优化
zipAlignEnabled true
// 移除无用的resource文件
shrinkResources true
}
- 命令行脚本
在Android工程根目录下会自动生成一个shell脚本 - gradlew
gradle脚本中包含了很多 task,可以通过task名来指定需要执行的task。
如:如果执行./gradlew assembleRelease会执行生成所有release工程包