Android studio使用之[gradle使用]
- gradle的相关介绍
- gradle相关命令
- 使用gradle进行多渠道打包
gradle的相关介绍
在Android Studio中有一个不可或缺的构建工具,就是gradle,我们所有的打包等操作都是需要使用gradle来进行的,往往在做android开发的时候我们都知道有个工具是叫gradle,那gradle是什么?为什么要有这样一个gradle工具?以及我们应该怎么去使用这样一个gradle呢?可能多数的程序员对这一块相对来说都是比较陌生的,只知道使用,但是却往往很多时候忽略了它的真正含义。在这里我就简单说一下我自己的理解。不喜勿喷!!!
1:首先是gradle的相关概念:
什么是gradle???
Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化建构工具。它使用一种基于Groovy的特定领域语言(DSL)来声明项目设置,抛弃了基于XML的各种繁琐配置。面向Java应用为主。当前其支持的语言限于Java、Groovy和Scala,计划未来将支持更多的语言。(简单总结下来也就是gradle就是一款相比以前来说更加智能一点的构建工具,其的诞生是基于jvm构建工具,解决的是繁琐的配置文件),那什么是构建????如果你需要盖一间房子,你是不是需要把砖,瓦,水泥,钢筋都需要准备好,然后请一个工人来,然后工人给你盖房子。我们也就可以把这一整个流程看做是一个构建的流程,首先你需要将一个完整的设计图纸和材料(整个项目),然后工人通过将材料组合,形成你图纸上想要的房子,但是如果工人出现偏差(参数修改),盖出来的房子就会改变,如果是材料或者图纸有点改变。那工人所盖的房子可能也会有一些偏差。可以简单的理解下,这是否就是一个完整的构建流程。
其实在15年初使用android studio的时候,那个时候gradle有时候都是需要自己去下载,配置的,而与现在的更加智能的android studio2.2版本相比,在install的时候,已经会自动默认去更新一些gradle版本了
2:先来看一下在android studio中安装的默认gradle的位置吧。当然也可以进行别的配置:
这是我android studio目录下,最新的gradle的相关位置
当然,还有在window下gradle的相关配置参数之类的,这个主要是在Administrator文件夹下的,后续下载的所有gradle版本貌似都在这个文件夹下面,有兴趣的可以自己去找一下
3:跟着我来查看android studio项目中的gradle脚本
从图上可以看到,在整个项目中有这样的几块都是与gradle相关的,当然每一个都是很重要的
先来说说项目的app/build.gradle吧:
//声明是android 应用程序,同样做java的同学也可以声明为java相关的
apply plugin: ‘com.android.application‘
//定义release版本的打包时间
def releaseTime() {
return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))
}
android {
//编译的sdk的版本
compileSdkVersion 25
//build tools的版本
buildToolsVersion "25.0.1"
//默认相关的配置
defaultConfig {
//包名
applicationId "com.zzf.camera.helloworld"
//最小的sdk(向下兼容)
minSdkVersion 22
//目标sdk
targetSdkVersion 25
// dex突破65535的限制
multiDexEnabled true
//版本号
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
//签名工具
signingConfigs {
debug {
// No debug config
}
release {
storeFile file("../yourapp.keystore")
storePassword "your password"
keyAlias "your alias"
keyPassword "your password"
}
}
// java版本
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
//对应用原始编译出来的apk进行名称的修改(默认编译出来的是app-debug.apk和app-release-unsigned.apk,此处都是未进行签名的)
android.applicationVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
def fileName
if (outputFile != null && outputFile.name.endsWith(‘.apk‘)) {
if (variant.buildType.name.equals(‘release‘)) {
fileName = "Hello.apk"
} else if (variant.buildType.name.equals(‘debug‘)) {
fileName = "Hello.apk"
}
output.outputFile = new File(outputFile.parent, fileName)
}
}
}
// 移除lint检查的error
lintOptions {
abortOnError false
}
//构建的类型,是debug版本还是release版本
buildTypes {
//debug版本的参数配置
debug{
signingConfig signingConfigs.debug
}
//release版本相关的版本配置
release {
//是否进行混淆
minifyEnabled false
//混淆相关的文件的位置
proguardFiles getDefaultProguardFile(‘proguard-android.txt‘), ‘proguard-rules.pro‘
signingConfig signingConfigs.release
}
}
}
//新建的工程,所以依赖的都是基础jar
dependencies {
compile fileTree(dir: ‘libs‘, include: [‘*.jar‘])
androidTestCompile(‘com.android.support.test.espresso:espresso-core:2.2.2‘, {
exclude group: ‘com.android.support‘, module: ‘support-annotations‘
})
compile ‘com.android.support:appcompat-v7:25.3.1‘
compile ‘com.android.support.constraint:constraint-layout:1.0.2‘
testCompile ‘junit:junit:4.12‘
}
以上就是关于文件的比较基本的相关配置
先来说说项目的gradle/wrap/目录吧:
gradle-wrapper.jar: 当前此project的所有构建工作主要就是依赖这样的一个jar包,后面会展示一下相关这个jar的具体内容。
gradle-wrapper.properties:类似于脚本配置文件,在引用的时候,需要给gradle-wrapper.jar提供相关的引用路径,一般情况下这个都是在项目建立的时候,整个gradle-wrapper.jar相关的调用路径等都是已经默认生成好了,所以是不需要再进行修改的
#Sat Apr 22 12:50:57 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
对应的是整个project目录下的,包括了所有的sub_project和modules都试用
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
//仓库
repositories {
jcenter()
}
dependencies {
classpath ‘com.android.tools.build:gradle:2.3.1‘
// 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
}
内容主要包含了两个方面:一个是声明仓库的源,这里可以看到是指明的jcenter(), 之前版本则是mavenCentral(), jcenter可以理解成是一个新的中央远程仓库,兼容maven中心仓库,而且性能更优。另一个是声明了android gradle plugin的版本
整个工程构建部分的Setting.gradle(系统自动更新,一般情况下不需要我们进行修改)
没有依赖module项目的操作
include ‘:app‘
依赖了包名为com.zzf.device.mediacodec项目之后
include ‘:app‘, ‘:com.zzf.device.mediacodec‘
整个工程构建部分的可执行的gradlew.bat
所有的gradle相关的执行全靠这个可执行命令,所有在整个构建的过程中,我们既可以去依赖android studio去帮我们构建,同时也可以使用gradlew.bat这样一个执行脚本,去构建
瞧一瞧,看一看,这个脚本都写了些什么??
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no ‘java‘ command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
里面有几个比较重要的代码:
1://设置java.exe
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if “%ERRORLEVEL%” == “0” goto init:
2://设置gradle-wrapper的目录
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
所以就可以看出来了,其实这个脚本大概的意思是
java -jar gradle-wrapper.jar//事实上就是去执行这个jar
简单了解gradle-wrapper.jar包源码:
整个jar包的Main函数是从GradleWrapperMain.class这里开始的,它会去从整个执行列表中去获取参数,然后在进行switch的过程,具体的代码不会在这里进行详细介绍。
public static void main(String[] args)
throws Exception
{
File wrapperJar = wrapperJar();
File propertiesFile = wrapperProperties(wrapperJar);
File rootDir = rootDir(wrapperJar);
CommandLineParser parser = new CommandLineParser();
parser.allowUnknownOptions();
parser.option(new String[] { "g", "gradle-user-home" }).hasArgument();
parser.option(new String[] { "q", "quiet" });
SystemPropertiesCommandLineConverter converter = new SystemPropertiesCommandLineConverter();
converter.configure(parser);
ParsedCommandLine options = parser.parse(args);
Properties systemProperties = System.getProperties();
systemProperties.putAll(converter.convert(options, new HashMap()));
File gradleUserHome = gradleUserHome(options);
addSystemProperties(gradleUserHome, rootDir);
Logger logger = logger(options);
WrapperExecutor wrapperExecutor = WrapperExecutor.forWrapperPropertiesFile(propertiesFile, logger);
wrapperExecutor.execute(args, new Install(logger, new Download(logger, "gradlew", wrapperVersion()), new PathAssembler(gradleUserHome)), new BootstrapMainStarter());
}
gradle相关命令(不进gradle-wrapper.jar看源码,讲原理,只讲使用)
先进入这个文件所在的目录下吧
执行可执行命令
传入的参数都是传入到jar中去执行的。
命令 | 执行意义 |
---|---|
-v | 版本号 |
clean | 清除app/目录下的build文件夹 |
build | 检查依赖并编译打包 |
assembleDebug | 编译并打Debug包 |
assembleRelease | 编译并打Release的包 |
installRelease | Release模式打包并安装 |
uninstallRelease | 卸载Release模式包 |
installDebug | Debug模式打包并安装 |
uninstallDebug | 卸载Debug模式包 |
具体的执行就不在这里执行了
使用gradle进行多渠道打包
第一步 在AndroidManifest.xml里配置PlaceHolder
<meta-data
android:name="UMENG_CHANNEL"
android:value="${UMENG_CHANNEL_VALUE}" />
第二步 在build.gradle设置productFlavors
android {
productFlavors {
xiaomi {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "xiaomi"]
}
_360 {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "_360"]
}
baidu {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "baidu"]
}
}
}
或者
android {
productFlavors {
xiaomi {}
_360 {}
baidu {}
wandoujia {}
}
productFlavors.all {
flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
}
}
第三步:执行命令
直接执行 ./gradlew assembleRelease 进行全部打包的过程
直接执行./gradlew assembleBaidujia,进行单个渠道的打包
直接执行./gradlew assembleBaiduRelease进行豌豆荚release版本的渠道打包
以上就是对gradle的一些简单的了解