AndroidStudio之Gradle
- AndroidStudio之Gradle
- AndroidStudio中的Gradle
- Gradle和Android Gradle插件
- AndroidStudio Gradle文件配置解读
- root build.gradle详解
- Moudle build.gradle详解
- gradle-wrapper.properties详解
- proguard-rules.pro详解
- gradle.properties详解
- settings.gradle详解
- local.properties详解
- 总结
这篇文章主要是跟大家探讨Gradle在AndroidStudio的使用,也会详解讲解各配置文件的使用,如果你对Gradle的基础不是很了解,可以先阅读Gradle之基础篇有助于对今天讨论这个主题的了解,了解原理使用Gradle才能随心所欲;
AndroidStudio中的Gradle
在AndroidStudio中的Gradle主要使用2个对象:
- build.gradle 对应 Project对象
- setting.gradle 对应 Setting对象
一个AS工程构建的整个过程是这样的:
1、构建开始时首先会创建一个Setting对象;
2、根据setting.gradle的内容来配置这个Setting对象;
3、通过这个Setting对象来加载Project,include多少个Moudle就会创建多少个Project;
4、根据build.gradle内容配置Project对象;
Gradle和Android Gradle插件
Gradle是独立于AndroidStudio运行的,AndroidStudio只是依赖了Gradle的插件,两者不可以混淆。
- AndroidStudio配置Gradle
1、如果选择“use defalut gradle wrapper(recommended)”,AS会根据项目中gradle-wrapper.properties文件配置查找gradle,gradle-wrapper.properties配置如下:
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
当项目开始编译时会先从环境变量中配置的gradle版本目录下查找wrapper/dists下对应的gradle,如果没有找到则会根据distributionUrl对应的url中下载。
2、当然也可以选择“use local gradle distribution”并加载本地gradle路径,
如果是选择本地gradle在开始编译时会直接使用本地的gradle。
- android gradle插件
在root目录下的build.gradle,配置gradle插件版本:
buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
}
}
- Gradle和Android Gradle插件
版本对应关系:
AndroidStudio Gradle文件配置解读
首先我们来看下AndroidStudio项目结构
从上图中可以看出一个完整的AndroidStudio项目包含一个或者多个Moudle以及gradle的配置文件
root build.gradle详解
/**
* buildscript里是gradle脚本执行所需依赖,分别是对应的maven库和插件
*/
buildscript {
/**
* 定义公共仓库
*/
repositories {
/**
* 公共仓库名称
*/
jcenter() //仓库名
mavenCentral() //仓库名
}
/**
* 定义依赖库
*/
dependencies {
/**
* Android Gradle 插件版本
*/
classpath 'com.android.tools.build:gradle:3.0.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
/**
* 项目本身需要的依赖、配置所有Moudle共用的依赖;
*/
allprojects {
repositories {
jcenter()
maven { url 'https://jitpack.io' }
}
}
/**
* 系统自动生成的task
*/
task clean(type: Delete) {
delete rootProject.buildDir
}
1、buildscript:里是gradle脚本执行所需依赖,分别是对应的maven库和插件;
2、repositories{}:定义公共仓库;
3、jcenter()、mavenCentral():公共仓库名称;
4、allprojects:项目本身需要的依赖、配置所有Moudle共用的依赖;
5、task clean:系统自动生成的task;
Moudle build.gradle详解
/**
* 配置当前Module构建属性
*/
apply plugin: 'com.android.application'
//apply plugin: 'com.android.library'
/**
* android{} 当前Moudle下项目构建配置选项
*/
android {
compileSdkVersion 26
buildToolsVersion 26.0.1
/**
* 配置项目编译版本号等属性,会覆盖AndroidManifest.xml中的配置
*/
defaultConfig {
applicationId "com.ailin.mvp"
minSdkVersion 19
targetSdkVersion 26
versionCode 1000
versionName "1.0"
/**
* 设置支持的SO库架构
*/
ndk {
abiFilters 'armeabi', 'x86', 'armeabi-v7a'
}
}
/**
* 配置release版本所需要的签名文件等
*/
signingConfigs {
//配置变会员release版本
release {
storeFile file("./mvpapp.jks")
storePassword "abc123"
keyAlias "mvpapp"
keyPassword "abc123"
}
}
/**
* 这里配置签名版本和调试版本,还可以自定义需要的版本
*/
buildTypes {
release {
/**
* 打开代码混淆功能
*/
minifyEnabled true
/**
* 指定signingConfigs中定义的签名配置
*/
signingConfig signingConfigs.release
/**
* 指定混淆代码的混淆文件,混淆文件由两部分组成:
* proguard-android.txt:系统默认的android程序的混淆文件,这个文件的目录在 <sdk目录>/tools/proguard/proguard-android.txt
* proguard-rules.pro:项目中自定义混淆文件
*/
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
debuggable true
minifyEnabled false
signingConfig signingConfigs.debug
}
}
}
/**
* 指定依赖仓库
*/
repositories {
/**
* 指定远程仓库
*/
maven { url 'https://jitpack.io' }
/**
* 指定当前Moudle根目录下文件名为libs的文件夹为本地仓库
*/
flatDir { dirs 'libs' }
}
dependencies {
/**
* 指定当前Moudle根目录下文件名为libs的文件夹为本地仓库,并且引入所有.jar结尾的依赖文件
*/
compile fileTree(include: ['*.jar'], dir: 'libs')
/**
* 依赖测试编译
*/
testCompile 'junit:junit:4.12'
/*
* 编译时指定编译release版本还是debug版本
*/
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.4-beta2'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta2'
/**
* 只在编译的时候执行依赖的库,但是库最终不打包到apk中
*/
annotationProcessor 'com.jakewharton:butterknife:8.2.1'
/**
* 在编译、运行时候需要依赖代码
*/
compile 'com.alibaba:fastjson:1.2.23'
/**
* 编译的时候才用得上,而运行时不需要,不会写入apk
*/
provided("com.tencent.tinker:tinker-android-anno:${TINKER_VERSION}") {
changing = true
}
/**
* 引入libary Moudle
*/
compile project(':RecyclerViewHelper')
compile project(':downloaderLib')
compile project(':playerview')
compile project(':tinkerLib')
}
/**
* 引入自定义扩展配置文件
*/
apply from: 'tinker_build.gradle'
还可以配置生成提供给java文件使用的变量
android {
defaultConfig {
......
buildConfigField "int", "count", "0"
}
buildTypes {
debug{
buildConfigField "boolean", "isDebug", "true"
}
}
}
添加完上面的代码,编译后会在build目录下的BuildConfig文件中生成,然后就可以在项目中使用了
gradle-wrapper.properties详解
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
这个配置文件上面已经分析过了,这里不在赘述了;
proguard-rules.pro详解
#指定代码的压缩级别
-optimizationpasses 5
#包名不混合大小写
-dontusemixedcaseclassnames
#不忽略非公共的库类
-dontskipnonpubliclibraryclasses
#优化/不优化输入的类文件
-dontoptimize
#预校验
-dontpreverify
#混淆时是否记录日志
-verbose
#混淆时所采用的算法
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
#忽略警告
-ignorewarning
#保护注解
-keepattributes *Annotation*
#保护反射的正常调用
-keepattributes Signature
-keepattributes EnclosingMethod
#不混淆哪些类
-keep public class * extends android.app.Fragment
-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
#不混淆所有View的子类及其子类的get、set方法
-keep public class * extends android.view.View {
public <init>(android.content.Context);
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
public void set*(...);
public *** get*();
}
#指定不混淆所有的JNI方法
-keepclasseswithmembernames class * {
native <methods>;
}
#不混淆Activity中参数类型为View的所有方法
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
#不混淆Parcelable和它的子类,还有Creator成员变量
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
#不混淆Serializable接口
-keepnames class * implements java.io.Serializable
#不混淆Serializable接口的子类中指定的某些成员变量和方法
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
!static !transient <fields>;
!private <fields>;
!private <methods>;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
#不混淆R类里及其所有内部static类中的所有static变量字段
-keepclassmembers class **.R$* {
public static <fields>;
}
#如果有用到Gson解析包的,直接添加下面这几行就能成功混淆,不然会报错。
-keep class sun.misc.Unsafe { *; }
-keep class com.google.gson.examples.android.model.** { *; }
#如果有用到WebView的JS调用接口,需加入如下规则。
-keepclassmembers class fqcn.of.javascript.interface.for.webview {
public *;
}
#apk包内所有class的内部结构
-dump class_files.txt
#未混淆的类和成员
-printseeds seeds.txt
#列出从apk中删除的代码
-printusage unused.txt
#混淆前后的映射
-printmapping mapping.txt
#忽略某个类的警告
-dontwarn com.unionpay.**
#不混淆某个类和成员变量
-keep class com.unionpay.** { *; }
-dontwarn android.support.**
-dontwarn com.flurry.**
-dontwarn com.paypal.**
-dontwarn org.lucasr.**
-dontwarn org.android.agoo.ut.impl.**
gradle.properties详解
- gradle.properties用于配置全局变量,比如定义一些常用的变量:
/**
* 指定JVM内存大小
*/
org.gradle.jvmargs=-Xmx1536m
/**
* 应用版本名称
*/
PACKAGE_ID=com.ailian.gradlestudy
/**
* 应用版本名称
*/
VERSION_NAME=1.0.0
/**
* 应用版本号
*/
VERSION_CODE=100
/**
* 支持库版本
*/
SUPPORT_LIBRARY=26.2.1
/**
* 最新支持SDK版本号
*/
ANDROID_BUILD_MIN_SDK_VERSION=19
/**
* TARGET_SDK_VERSION
*/
ANDROID_BUILD_TARGET_SDK_VERSION=24
/**
* BUILD_SDK_VERSION
*/
ANDROID_BUILD_SDK_VERSION=26
/**
* BUILD_TOOLS_VERSION
*/
ANDROID_BUILD_TOOLS_VERSION=26.0.3
- 在其他配置文件中的使用
android {
compileSdkVersion project.ANDROID_BUILD_SDK_VERSION as int
defaultConfig {
applicationId project.APPLICATION_ID
minSdkVersion project.ANDROID_BUILD_MIN_SDK_VERSION as int
targetSdkVersion project.ANDROID_BUILD_TARGET_SDK_VERSION as int
versionCode = project.VERSION_CODE as int
versionName project.VERSION_NAME
}
}
settings.gradle详解
include ':app', ':RecyclerViewHelper', ':downloaderLib', ':playerview', ':tinkerLib'
settings.gradle主要用于Moudle加载配置:
1、这里需要有个’:app’,这个Moudle是创建项目时默认生成的,如果项目中只有一个’:app’Moudle,则settings.gradle可以不需要配置,因为gradle会默认加载名为app的Moudle;
2、’:app’模块名可以修改名字,如果改了Moudle名称,则必须在settings.gradle进行声明;
3、’:app’模块为项目主要模块,app Moudle与其他Moudle主要区别在于:
app:
apply plugin: 'com.android.application'
其他Moudle:
apply plugin: 'com.android.library'
local.properties详解
/**
* 配置项目支持NDK
*/
ndk.dir=/Users/ailian/sdk/ndk-bundle
/**
* 配置项目支持SDK
*/
sdk.dir=/Users/ailian/sdk
local.properties还可以添加其他属性
keyfile=./groovy.jks
keyAlias=groovy
keyPassword=adb123
storePassword=adb123
配置文件中使用方式
signingConfigs {
release {
def sdkDir = properties.getProperty('keyfile')
storeFile file(sdkDir)
def keyAliass = properties.getProperty('keyAlias')
keyAlias keyAliass
def keyPasswords = properties.getProperty('keyPassword')
keyPassword keyPasswords
def storePasswords = properties.getProperty('storePassword')
storePassword storePasswords
}
}
好了,到这里AndroidStudio中有关gradle的配置都讲完了,当然gradle还有很多配置,感兴趣的同学可以自行研究,如果上面解释有什么不对的地方,欢迎指正;
总结
还是开篇中讲的,知其然也要知其所以然,想要用gradle为我们构建强大的项目,就必须了解它的原理和用法。