Gradle
使用 Android Studio 都知道 Gradle,在 SimpleNews 项目中,前期的时候并不是很了解 Gradle 语法等,只是使用 Android Studio 默认的配置来构建,后续也只是关注在功能方向,没有过多的了解 Gradle 使用,趁此重构机会就好好认识 Gradle。
我们来看下维基百科简单了解下概念:
可以看到 Gradle 的优势,我之前也使用过 Ant 打包,相对于Ant xml 的编写,Gradle 使用简单易理解。
如果我们不是负责项目的打包或者渠道发布等工作,这里我们了解下 Gradle 常用的基本配置就可以了,也能满足我们的日常需求。
要是想精通的话,建议看看 Gradle for Android 这本书,并动手操练,这里推荐 Android Gradle 插件中文指南
SimpleNews.io 项目中使用的 gradle build 版本是 gradle:2.3.2
接下来挨个文件看,项目中的基本上都添加了注释,很容易理解,后续再清理。
基本的 settings.gradle 文件
include ':app', ':library'
//包含多个模块即多个module
Android 项目级别的 build.gradle 文件
// Top-level build file where you can add configuration options common to all sub-projects/modules.
//顶级的构建文件,需要到子项目中添加依赖
//应用配置文件,完事之后可以在全局引用
apply from: "config.gradle"
// 中央远程仓库,兼容maven中心仓库
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.2'//项目使用 gradle:2.3.2 版本 build
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
//不要再这里添加依赖,在各自的module build.gradle中添加依赖
}
}
//为所有的工程的repositories配置为jcenters,JCenter类似maven库,不需要任何额外的配置
allprojects {
repositories {
jcenter()
}
}
//buildscript 方法是定义了全局的相关属性,repositories定义了jcenter作为仓库。一个仓库代表着你的依赖包的来源,
// 例如maven仓库。dependencies用来定义构建过程。这意味着你不应该在该方法体内定义子模块的依赖包,你仅仅需要定义默认的Android插件就可以了,
// 因为该插件可以让你执行相关Android的tasks。
Android 项目 App 级别 build.gradle 文件
apply plugin: 'com.android.application'
//该 plugin 为一个 com.android.application 程序,也就是应用程序,如果你的 plugin 是一个库,那么自然也就是apply plugin: 'com.android.library'
android {
compileSdkVersion rootProject.ext.android.compileSdkVersion //编译的 SDK API 版本
buildToolsVersion rootProject.ext.android.buildToolsVersion //构建工具版本
//默认配置&核心属性,该属性会重写在AndroidManifest.xml中的对应属性
defaultConfig {
applicationId rootProject.ext.android.applicationId//配置包名的
minSdkVersion rootProject.ext.android.minSdkVersion //支持最小的 SDK 版本
targetSdkVersion rootProject.ext.android.targetSdkVersion
versionCode rootProject.ext.android.versionCode//版本号
versionName rootProject.ext.android.versionName//版本名称
}
//构建类型,常用的有release和debug两种
buildTypes {
release {
minifyEnabled true //是否启动混淆
shrinkResources true //是否移除无用资源文件,shrinkResources依赖于minifyEnabled
// 混淆文件的位置
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
repositories {
jcenter()
maven { url "https://jitpack.io" }
}
//依赖管理,可以添加远程依赖 和 本地依赖libs等
dependencies {
//将libs文件夹中所有的jar文件视为依赖包。
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
//添加依赖包
compile project(':library')
//依赖远程仓库
compile rootProject.ext.dependencies.design
compile rootProject.ext.dependencies.cardview
compile rootProject.ext.dependencies.circleimageview
compile rootProject.ext.dependencies.sufficientlysecure
}
Android 项目 Library 级别 build.gradle 文件
这里的配置基本上和 App 中的配置一样,之前介绍过,使用 config.gradle 来统一全局变量,就不多介绍了,不知道的可以查看第一篇
apply plugin: 'com.android.library'
android {
compileSdkVersion rootProject.ext.android.compileSdkVersion
buildToolsVersion rootProject.ext.android.buildToolsVersion
defaultConfig {
minSdkVersion rootProject.ext.android.minSdkVersion
targetSdkVersion rootProject.ext.android.targetSdkVersion
versionCode rootProject.ext.android.versionCode
versionName rootProject.ext.android.versionName
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile rootProject.ext.dependencies.appcompat
compile rootProject.ext.dependencies.gson
compile rootProject.ext.dependencies.glide
compile rootProject.ext.dependencies.okhttp
compile rootProject.ext.dependencies.rxandroid
compile rootProject.ext.dependencies.eventbus
}
so、jar、aar文件
jar:只包含了 class 文件与清单文件,不包含资源文件;
aar:包含所有资源,class以及res资源文件。
aar使用
当你构建你的library项目,aar文件将会在 build/output/aar/下生成。
可以创建一个 aars 文件夹来存放 aar 文件,并将本目录下所有的 aar 文件作为依赖包,例如:
repositories {
flatDir {
dirs 'aars'
}
}
so:用c或者c++写的 library 会被叫做 so 包,Android 插件默认情况下支持native包,你需要把.so文件放在对应的文件夹中:
app
├── AndroidManifest.xml
└── jniLibs
├── armeabi
│ └── nativelib.so
├── armeabi-v7a
│ └── nativelib.so
├── mips
│ └── nativelib.so
└── x86
└── nativelib.so
使用系统的 load 方法,就能加载,有两种方式,这里就不多介绍了,等用到了在说。
其他文件
1、gradle-wrapper.properties
#Fri May 26 10:09:38 CST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
#声明gradle的目录与下载路径以及当前项目使用的gradle版本,一般不会更改的
2、proguard-rules.pro
每一个 module 都会有自己的 proguard-rules.pro 文件,用来编写混淆规则,有一些是不能被混淆的
例如:一些js注入类是不能被混淆的,否则调用找不到方法。
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
3、gradle.properties
说到这个文件就要说到之前的 config.gradle 来统一全局变量,config.gradle 只是一种方式,我们还可以在 gradle.properties 中
定义常量。
例如(不是本项目中的使用方式,摘自网络):
# 应用版本名称
VERSION_NAME=1.0.0
# 应用版本号
VERSION_CODE=100
# 支持库版本
SUPPORT_LIBRARY=24.2.1
# MIN_SDK_VERSION
ANDROID_BUILD_MIN_SDK_VERSION=14
# TARGET_SDK_VERSION
ANDROID_BUILD_TARGET_SDK_VERSION=24
# BUILD_SDK_VERSION
ANDROID_BUILD_SDK_VERSION=24
# BUILD_TOOLS_VERSION
ANDROID_BUILD_TOOLS_VERSION=24.0.3
android {
compileSdkVersion project.ANDROID_BUILD_SDK_VERSION as int
buildToolsVersion project.ANDROID_BUILD_TOOLS_VERSION
defaultConfig {
applicationId project.APPLICATION_ID
versionCode project.VERSION_CODE as int
versionName project.VERSION_NAME
minSdkVersion project.ANDROID_BUILD_MIN_SDK_VERSION as int
targetSdkVersion project.ANDROID_BUILD_TARGET_SDK_VERSION as int
}
}
4、local.properties
这个比较简单,就是配置项目 NDK、SDK 路径
总结
本文只是简单的介绍了项目中使用的 Gradle 脚本含义和简单用法,只是 Gradle 使用当中的冰山一角,之后会深入打包功能,让项目越来越完善。
参考
Gradle for Android 第一篇( 从 Gradle 和 AS 开始 )
SimpleNews 项目的重构之旅其他文章
SimpleNews 项目的重构之旅(1) -项目架构定位 & Gradle 全局配置
SimpleNews 项目的重构之旅(2) - 整理项目 .gitignore 文件
SimpleNews 项目的重构之旅(3) -EventBus 接入
SimpleNews 项目的重构之旅(4) -Gradle for Android 基础知识汇总
SimpleNews 项目的重构之旅(5) - Android Gradle 打包&混淆应用
SimpleNews 项目的重构之旅(6) - 命名规范 & Android Toolbar
SimpleNews 项目的重构之旅(7) - 改头换面&深度清理