本文为稀土技能社区首发签约文章,14天内禁止转载,14天后未获授权禁止转载,侵权必究!
1、前语
Gradle的指令有许多,熟悉常用指令之后,在日常开发中,不只能够提高功率,也能够辅佐咱们快速定位并解决编译问题;而且某些情况下指令行(CLI)与按钮履行的编译结果是不一样的,比方构建时要传参(-P),所以就单拎出来一篇解说,希望对你有协助~
1、Gradle指令
1.1、gradlew
Gradle履行指令行首要用到的是Gradle Wrapper
,关于Gradle Wrapper的介绍,在前文(【Gradle-2】一文搞懂Gradle装备)中有介绍,这儿不再赘述。
所以咱们常用的./gradlew
(Mac),gradlew即Gradle Wrapper的简写。
Gradle Wrapper工作流:
再来看下gradlew
的脚本内容
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> (.*)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname "$PRG"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS "-Xdock:name=$APP_NAME" "-Xdock:icon=$APP_HOME/media/gradle.icns""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`=""$arg""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\n "$i" | sed "s/'/'\\''/g;1s/^/'/;$s/$/' \\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS ""-Dorg.gradle.appname=$APP_BASE_NAME"" -classpath ""$CLASSPATH"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
exec "$JAVACMD" "$@"
代码量不多,gradlew首要干了几件事:
- 获取电脑系统内核的信息,JRE环境信息等;
- 设置classpath途径;
- 履行java指令东西,调用gradle jar包的class文件;
1.2、指令大全
当咱们想知道一个东西有哪些指令的时分,最简单直接的方式就是使用help
指令检查支撑哪些,然后从中找到咱们想要的。
履行:
./gradlew --help
输出:
USAGE: gradlew [option...] [task...]
-?, -h, --help Shows this help message.
-a, --no-rebuild Do not rebuild project dependencies.
-b, --build-file Specify the build file. [deprecated]
--build-cache Enables the Gradle build cache. Gradle will try to reuse outputs from previous builds.
-c, --settings-file Specify the settings file. [deprecated]
--configuration-cache Enables the configuration cache. Gradle will try to reuse the build configuration from previous builds. [incubating]
--configuration-cache-problems Configures how the configuration cache handles problems (fail or warn). Defaults to fail. [incubating]
--configure-on-demand Configure necessary projects only. Gradle will attempt to reduce configuration time for large multi-project builds. [incubating]
--console Specifies which type of console output to generate. Values are 'plain', 'auto' (default), 'rich' or 'verbose'.
--continue Continue task execution after a task failure.
-D, --system-prop Set system property of the JVM (e.g. -Dmyprop=myvalue).
-d, --debug Log in debug mode (includes normal stacktrace).
--daemon Uses the Gradle daemon to run the build. Starts the daemon if not running.
--export-keys Exports the public keys used for dependency verification.
-F, --dependency-verification Configures the dependency verification mode. Values are 'strict', 'lenient' or 'off'.
--foreground Starts the Gradle daemon in the foreground.
-g, --gradle-user-home Specifies the Gradle user home directory. Defaults to ~/.gradle
-I, --init-script Specify an initialization script.
-i, --info Set log level to info.
--include-build Include the specified build in the composite.
-M, --write-verification-metadata Generates checksums for dependencies used in the project (comma-separated list)
-m, --dry-run Run the builds with all task actions disabled.
--max-workers Configure the number of concurrent workers Gradle is allowed to use.
--no-build-cache Disables the Gradle build cache.
--no-configuration-cache Disables the configuration cache. [incubating]
--no-configure-on-demand Disables the use of configuration on demand. [incubating]
--no-daemon Do not use the Gradle daemon to run the build. Useful occasionally if you have configured Gradle to always run with the daemon by default.
--no-parallel Disables parallel execution to build projects.
--no-scan Disables the creation of a build scan. For more information about build scans, please visit https://gradle.com/build-scans.
--no-watch-fs Disables watching the file system.
--offline Execute the build without accessing network resources.
-P, --project-prop Set project property for the build script (e.g. -Pmyprop=myvalue).
-p, --project-dir Specifies the start directory for Gradle. Defaults to current directory.
--parallel Build projects in parallel. Gradle will attempt to determine the optimal number of executor threads to use.
--priority Specifies the scheduling priority for the Gradle daemon and all processes launched by it. Values are 'normal' (default) or 'low'
--profile Profile build execution time and generates a report in the <build_dir>/reports/profile directory.
--project-cache-dir Specify the project-specific cache directory. Defaults to .gradle in the root project directory.
-q, --quiet Log errors only.
--refresh-dependencies Refresh the state of dependencies.
--refresh-keys Refresh the public keys used for dependency verification.
--rerun-tasks Ignore previously cached task results.
-S, --full-stacktrace Print out the full (very verbose) stacktrace for all exceptions.
-s, --stacktrace Print out the stacktrace for all exceptions.
--scan Creates a build scan. Gradle will emit a warning if the build scan plugin has not been applied. (https://gradle.com/build-scans)
--status Shows status of running and recently stopped Gradle daemon(s).
--stop Stops the Gradle daemon if it is running.
-t, --continuous Enables continuous build. Gradle does not exit and will re-execute tasks when task file inputs change.
--update-locks Perform a partial update of the dependency lock, letting passed in module notations change version. [incubating]
-v, --version Print version info.
-w, --warn Set log level to warn.
--warning-mode Specifies which mode of warnings to generate. Values are 'all', 'fail', 'summary'(default) or 'none'
--watch-fs Enables watching the file system for changes, allowing data about the file system to be re-used for the next build.
--write-locks Persists dependency resolution for locked configurations, ignoring existing locking information if it exists
-x, --exclude-task Specify a task to be excluded from execution.
简写:
./gradlew -?
// or
./gradlew -h
能够看到上面的输出现已列出来了许多指令,可能有些见过有些没见过,下面将把常用的提炼出来解说,并进行分类。
1.3、指令结构
gradle [taskName...] [--option-name...]
多个任务用空格分隔。
2、Gradle相关
2.1、检查Gradle版别
常见的检查Gradle版别有两种方式。
第一种是直接在gradle>wrapper>gradle-wrapper.properties文件下检查distributionUrl
所使用的gradle版别下载地址:
distributionUrl=https://services.gradle.org/distributions/gradle-7.4-bin.zip
这儿的distributionUrl即表明当时所用的gradle版别为7.4。
第二种就是使用指令行的方式检查当时版别。
履行:
./gradlew -version
// or
./gradlew -v
输出:
------------------------------------------------------------
Gradle 7.4
------------------------------------------------------------
Build time: 2022-02-08 09:58:38 UTC
Revision: f0d9291c04b90b59445041eaa75b2ee744162586
Kotlin: 1.5.31
Groovy: 3.0.9
Ant: Apache Ant(TM) version 1.10.11 compiled on July 10 2021
JVM: 11 (Oracle Corporation 11+28)
OS: Mac OS X 10.16 x86_64
2.2、晋级Gradle
常见的晋级Gradle有3种方式。
第一种,先手动修正wrapper.properties文件下distributionUrl指向的版别,再手动修正Android Gradle Plugin(AGP)版别,然后重新sync。
第二种,翻开file>Project Structure修正AGP和Gradle的版别,然后apply。
第三种,用指令行的方式(官方引荐,不过跟着AS一同升也是能够的):
./gradlew wrapper --gradle-version 7.5.1
3、编译指令
3.1、检查依靠并编译打包
./gradlew build
3.2、编译并打出Debug包
./gradlew assembleDebug
3.3、编译打出Debug包并安装
./gradlew installDebug
3.4、编译并打出Release包
./gradlew assembleRelease
3.5、编译打出Release包并安装
./gradlew installRelease
3.6、Debug/Release编译并打印日志
./gradlew assembleDebug --info
// or
./gradlew assembleRelease --info
4、铲除指令
铲除构建目录下的产品。
./gradlew clean
等同于Build->Clean Project。
5、卸载指令
5.1、卸载Debug/Release安装包
./gradlew uninstallDebug
// or
./gradlew uninstallRelease
输出:
Uninstalling com.yechaoa.gradlex (from app:debug) from device 'Pixel_5_API_31(AVD) - 12' (emulator-5554).
Uninstalled com.yechaoa.gradlex from 1 device.
5.2、adb卸载
在Android Studio中履行是直接卸载的当时项目安装包,如果是adb履行则需求指定包名
。
adb uninstall com.yechaoa.gradlex
6、调试指令
调试指令在定位编译问题的时分十分有用。
当咱们遇到编译过错的时分,经常会看到这个提示:
* Try:
> Run gradle tasks to get a list of available tasks.
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
6.1、编译并打印仓库日志
./gradlew assembleDebug --stacktrace
// or
./gradlew assembleDebug -s
具体版:
./gradlew assembleDebug --full-stacktrace
// or
./gradlew assembleDebug -S
6.2、日志等级
有时分构建日志会有许多,看到的可能不全,甚至不是真正的编译问题,而构建日志又不能像logcat
那样能够可视化的挑选,这个时分就需求用日志等级来挑选一下。
-q,--quiet
仅记载过错。
-w,--warn
将日志等级设置为警告。
-i,--info
将日志等级设置为信息。
-d,--debug
调试形式(包含正常的stacktrace)。
示例:
./gradlew assembleDebug -w
7、任务相关
7.1、检查首要Task
./gradlew tasks
7.2、检查一切Task
./gradlew tasks --all
7.3、履行Task
./gradlew taskName
// or
./gradlew :moduleName:taskName
一起,可在AS右侧东西类Gradle中检查项目及module的Task,并能够点击履行对应Task。
8、检查依靠
编译有许多问题都是依靠导致的过错,检查依靠能帮咱们快速定位问题所在。
8.1、检查项目根目录下的依靠
./gradlew dependencies
8.2、检查app模块下的依靠
./gradlew app:dependencies
8.3、检查依靠输出到文件
./gradlew app:dependencies > dependencies.txt
示例:
9、功能相关
9.1、离线编译
./gradlew assembleDebug --offline
9.2、构建缓存
./gradlew assembleDebug --build-cache // 敞开
./gradlew assembleDebug --no-build-cache // 不敞开
9.3、装备缓存
./gradlew assembleDebug --configuration-cache // 敞开
./gradlew assembleDebug --no-configuration-cache // 不敞开
9.4、并行构建
./gradlew assembleDebug --parallel // 敞开
./gradlew assembleDebug --no-parallel // 不敞开
以上9.1-9.4的装备也都能够在gradle.properties
中装备。
示例:
#并行编译
org.gradle.parallel=true
#构建缓存
org.gradle.caching=true
9.5、编译并输出功能报告
./gradlew assembleDebug --profile
功能报告坐落构建项目的GradleX/build/reports/profile/
途径下
See the profiling report at: file:///Users/yechao/AndroidStudioProjects/GradleX/build/reports/profile/profile-2022-11-29-23-13-29.html
输出的是html文件,用浏览器翻开:
9.6、编译并输出更具体功能报告
./gradlew assembleDebug --scan
首次履行需求邮箱验证,授权即可,完事之后即可翻开链接,scan
报告内容比profile愈加具体。
10、动态传参
再来介绍一个比较常用的传参属性,--project-prop
,咱们一般常用-P
表明,用来设置根项目的项目属性。
10.1、获取参数
示例:
./gradlew assembleDebug -PisTest=true
这儿咱们用-P传了一个isTest
字段,并赋值为true
。
那在代码里如何获取这个参数呢?然后在build.gradle中编写如下代码:
if (hasProperty("isTest")){
println("---hasProperty isTest yes")
}else {
println("---hasProperty isTest no")
}
咱们能够用hasProperty
来获取指令行(CLI)的参数,module或许插件也能够这么获取:
project.property('isTest')
然后咱们用上面的指令编译看下输出:
➜ GradleX git:(master) ✗ ./gradlew assembleDebug -PisTest=true
---Gradle:开始初始化了
---Gradle:settingsEvaluated Settings目标评价结束
---Gradle:projectsLoaded 预备加载Project目标了
> Configure project :
---Gradle:Projec beforeEvaluate Project开始评价,目标是 = GradleX
---hasProperty isTest yes // --- 看这儿 ---
---Gradle:Projec afterEvaluate Project评价结束,目标是 = GradleX
> Configure project :app
---Gradle:buildFinished 构建结束了
能够看到现已打印出来了。
还没完,获取到参数是不错,但是还没获取到参数的值。
10.2、获取参数值
咱们能够用getProperty()
来获取:
if (hasProperty("isTest")) {
println("---hasProperty isTest yes")
if (Boolean.valueOf(getProperty('isTest'))) {
println("---isTest true")
} else {
println("---isTest false")
}
} else {
println("---hasProperty isTest no")
}
注意,getProperty('isTest')
这儿要用单引号,另外指令行里边的参数值都是目标,还需求根本数据类型转化一下,即Boolean.valueOf(getProperty('isTest'))
。
10.3、自定义操作
ok,现在咱们就能够针对获取的参数去做一些自定义的操作了,比方修正咱们的依靠。
app>build.gradle:
dependencies {
implementation 'androidx.core:core-ktx:1.7.0'
if (project.hasProperty("isTest")) {
println("---hasProperty isTest yes")
if (Boolean.valueOf(getProperty('isTest'))) {
println("---isTest true")
implementation 'com.yechaoa.gradlex.devtools:devtools:1.1.1'
} else {
println("---isTest false")
implementation 'com.yechaoa.gradlex.devtools:devtools:2.2.2'
}
} else {
println("---hasProperty isTest no")
}
testImplementation 'junit:junit:4.13.2'
}
这儿举例,在isTest=true
的时分依靠了devtools 1.1.1版别,isTest=false
时依靠了devtools 2.2.2版别。
除了dependencies里边的依靠之外,Plugin、Task之类的也能够经过动态传参的方式去做自定义操作。
11、总结
本文介绍了Gradle Command-Line Interface(CLI)相关的常识,像调试指令、检查依靠、功能相关、动态传参这些,在定位问题、提高功率的时分还是十分有用的,希望能给你带来收成。(别忘了三连啊喂~)
12、Github
github.com/yechaoa/Gra…
13、相关文档
- Command-Line Interface
- The Gradle Wrapper
- Shell脚本gradle指令和gradlew指令的区别
- Gradle Logging
- Build Environment
- Gradle Project
- 深度探究 Gradle 自动化构建技能(一、Gradle 核心装备篇)