android-gradle记录
android-gradle记录
前篇
- Gradle 2 用户指南 - https://wiki.jikexueyuan.com/project/gradle-2-user-guide/
自定义任务 Task
- Gradle Task的使用 - https://www.jianshu.com/p/cd1a78dc8346
- Android Gradle 自定义Task 详解 - https://blog.csdn.net/zhaoyanjun6/article/details/76408024
gradle 中定义
1 | task mylog() { |
构建指定任务
以构建 testapp 模块的 Release 版本为例, 也就是 :testapp:assembleRelease
任务.
命令行方式
1 | E:\its_rummy\Rummy_AndroidStudio>gradlew :testapp:assembleRelease |
gui 方式
在 testapp 模块的 build.gradle 中加入自定义任务, 依赖上 assembleRelease 任务即可.
1 | task a_buildApplication() { |
怎么获取任务名
直接 build 的时候可以看到执行的所有任务
1 | > Task :testapp:assembleDebug UP-TO-DATE |
去掉 任务
比如: 去掉 android 构建 apk 时的 verifyReleaseResources
任务
1 | tasks.whenTaskAdded {task -> |
自定义 插件 Plugin
- Gradle自定义插件实现自定义Task - https://www.jianshu.com/p/1b506e0f8a5b
执行多个命令行
参考: execute multiple commands from task - https://stackoverflow.com/questions/35561014/gradle-execute-multiple-commands-from-task
错误姿势
1
2
3
4
5task adbRestart(type: Exec) {
workingDir "$projectDir"
commandLine 'cmd', '/c', 'adb kill-server'
commandLine 'cmd', '/c', 'adb start-server'
}正确姿势
1
2
3
4
5
6
7
8
9
10
11
12task adbRestart() {
doLast {
exec {
workingDir "$projectDir"
commandLine 'cmd', '/c', 'adb kill-server'
}
exec {
workingDir "$projectDir"
commandLine 'cmd', '/c', 'adb start-server'
}
}
}
执行任务
先 cd 到 build.gradle 所在目录
执行单个任务. 命令:
gradle xxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23E:\its_rummy\Rummy_AndroidStudio\app (master -> origin)
$ D:\android-studio-3.4.2\gradle\gradle-5.1.1\bin\gradle a_ItsCopyJar
> Configure project :app
--- a_DelTempDir
--- a_ItsCopyAAR
--- a_unzip
--- a_ItsCopyJar
--- its build
hello world 111
> Task :app:lint
Ran lint on variant release: 41 issues found
Ran lint on variant debug: 41 issues found
Wrote HTML report to file:///E:/its_rummy/Rummy_AndroidStudio/app/build/reports/lint-results.html
Wrote XML report to file:///E:/its_rummy/Rummy_AndroidStudio/app/build/reports/lint-results.xml
Deprecated Gradle features were used in this build, making it incompatible with Gradle 6.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/5.1.1/userguide/command_line_interface.html#sec:command_line_warnings
BUILD SUCCESSFUL in 9s
54 actionable tasks: 4 executed, 50 up-to-date执行多个任务. 命令:
gradle xxx yyy
gradlew 构建 processDebugManifest 显示 报错信息
模块a 引用 模块b 时, 合并 Manifest 报错, 但是给的信息很有先, 只有 Manifest merger failed with multiple errors
查看具体的信息可以在 项目的根目录 (模块目录的上一级目录) 执行: gradlew processDebugManifest --stacktrace -info
, 然后搜索关键之 error, fail 之类的就可以找到错误信息
1 | E:\its_rummy\Rummy_AndroidStudio>gradlew processDebugManifest --stacktrace -info |
参考: Manifest merger failed with multiple errors, see logs问题处理 - https://blog.csdn.net/Picasso_L/article/details/53085299
gradle 中写代码逻辑
- Gradle中的buildScript代码块 - https://www.cnblogs.com/huang0925/p/3940528.html
- Gradle全局变量不在buildscript中的范围内 - https://www.thinbug.com/q/27031587
gradle 在执行脚本时,会优先执行 buildscript 代码块中的内容,然后才会执行剩余的 build 脚本。
所以在 buildscript 块中, 使用外部定义的变量是就会报错, 如:
1 | def aaa = {} |
会报错; Could not get unknown property 'aaa'
执行某个任务
Gradle高阶-Task执行 - https://juejin.cn/post/6844904016778903560
如果 cd 到项目根目录, 就需要带上模块
1
gradlew :Hello:assembleRelease --stacktrace
表示执行 Hello 模块的 assembleRelease 任务
assembleRelease 在 as 中看到的只是 assemble, release 指的是 gradle 中的构建类型, 在任务中拼接起来就是 assembleRelease
1
2
3
4
5
6
7android {
buildTypes {
release {
}
}
}如果自定义 构建类型 wilker, 则需要在 所有依赖的工程的 gradle 中都添加这个类型
1
2
3
4
5
6
7android {
buildTypes {
wilker {
}
}
}执行任务命令则是
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23gradlew :Hello:assembleWilker --stacktrace
---
### 定义全局变量
- 在 *gradle.properties* 中定义的变量, 可以在项目中的所有模块中使用

---
### 在项目中引入任意目录下的模块
- 这个引入配置在 *settings.gradle* 中配置, 比如引入 *:apicocos* 模块
```json
include ':apicocos'
project(':apicocos').projectDir = new File("E:/workspace/cocos/TestAtlas/build/android-001/proj/apicocos")
就可以在该项目中使用该模块的资源
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25dependencies {
implementation project(':apicocos')
}
---
### 读取命令行参数
- 参考: 向gradle命令任务传递命令行参数的不同方法 - https://juejin.cn/post/7120878611376111646
1. 在 gradle 中读取参数
```json
if (project.hasProperty("flagSo11")) {
println("------------ flagSo11:")
println(flagSo11)
}
if (project.hasProperty("flagSo22")) {
println("------------ flagSo22:")
println(flagSo22)
}
命令行中加入参数
1
$ gradlew :MyGame:assembleRelease --stacktrace -PflagSo11=aaa -PflagSo22=bbb
结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19------------ flagSo11:
aaa
------------ flagSo22:
bbb
---
### 命令行构建 apk
1. 生成 wrapper
```json
set JAVA_HOME=C:\Users\asd01\Desktop\Java\jdk1.8.0_144
set ANDROID_SDK_ROOT=C:\Users\asd01\Desktop\android_sdk
set GRADLE_ROOT=C:\Users\asd01\Desktop\gradle-6.7.1
%GRADLE_ROOT%\bin/gradle wrapper
执行任务, 也就是构建 apk 等任务 (不能和生成 wrapper 同时执行, 不知道为啥)
1
2
3
4
5set JAVA_HOME=C:\Users\asd01\Desktop\Java\jdk1.8.0_144
set ANDROID_SDK_ROOT=C:\Users\asd01\Desktop\android_sdk
set GRADLE_ROOT=C:\Users\asd01\Desktop\gradle-6.7.1
gradlew :launcher:bundleRelease --stacktrace --info- 格式为
:模块名:任务名
- 格式为
清楚
1
gradlew clean
gradle 命令输出日志
有两级输出重定向, 第二级才有报错堆栈信息
1
$ gradlew :testapp:assembleRelease --stacktrace > "c:/aaa.txt" 2> "c:/bbb.txt"
踩坑
maven http 链接不安全
报错: redirect to a secure protocol (like HTTPS)
原因是 gradle 7.0+ 之后, maven 仓库的链接默认要求是 https, 如果是 http, 需要配置安全性字段 allowInsecureProtocol = true
1 | buildscript { |
gradle 插件要求使用 Java 11
报错: Android Gradle plugin requires Java 11 to run. You are currently using Java 1.8
解决办法, 下载 jdk11, 然后修改 as 配置指向 jdk11
gradle 引入错误 material
报错:
Can't determine type for tag '<macro name="m3_comp_assist_chip_container_shape">?attr/shapeAppearanceCornerSmall</macro>'
解决办法: 将 material 版本降低一点即可
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30implementation 'com.google.android.material:material:1.8.0'
// 修改为
implementation 'com.google.android.material:material:1.0.0'
---
#### 转换 activity 报错
- 报错: `Failed to transform activity-1.8.0.aar`
- 解决办法:
1. 将 项目级 和全局的 gradle.properties 配置里增加 `android.enableJetifier=false`
2. 引入错误库, 将 `implementation 'androidx.constraintlayout:constraintlayout:2.1.4'`
---
#### 报错: AAPT2
- 报错: AAPT2 aapt2-4.1.0-6503028-windows Daemon #0: Unexpected error during link, attempting to stop daemon.
- 解决办法: 项目级 build.gradle 升级 构建工具
```json
dependencies {
classpath 'com.android.tools.build:gradle:4.2.0'
classpath 'com.google.gms:google-services:4.3.3'
}
主题报错
- 报错: java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.
- 解决办法: 将 AppCompatActivity 修改为 Activity
样式 xml 报错
报错 Can’t determine type for tag m3_comp_assist_chip_container_shape shapeAppearanceCornerSmall 错误
解决办法: material 和 constraintlayout 降级
1
2implementation 'com.google.android.material:material:1.6.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
创建 handler 报错
报错: Can’t create handler inside thread that has not called Looper.prepare()
原因:非主线程中没有开启Looper,而Handler对象必须绑定Looper对象需要调用Looper.prepare()来给线程创建一个消息循环,调用Looper.loop()来使消息循环起作用。
解决办法: 在主线程中创建即可
1
2
3
4Tools.runOnUiThread(() -> {
// 执行代码
SplashHelper.setIns(new SplashNew());
});
构建时检查报错找不到 Vendor 类
报错: java.lang.NoClassDefFoundError: com/android/tools/lint/client/api/Vendor
解决办法: 加入 lint 禁用配置
1
2
3
4
5
6android {
...
lintOptions {
checkReleaseBuilds false
}
}