unity-android和gradle升级
unity-android和gradle升级, 使用的 unity 版本是 2018.4.36f1 (LTS)
前篇
适配 android 11,12 的需要
sdk 升级到 最新版本后 unity 打包问题
报错无法识别的属性名模块: unrecognized Attribute name MODULE
完整报错
1
2
3
4
5
6
7
8
9
10
11
12CommandInvokationFailure: Gradle build failed.
D:\unity2018.4.36f1\Editor\Data\PlaybackEngines\AndroidPlayer/Tools\OpenJDK\Windows\bin\java.exe -classpath "D:\unity2018.4.36f1\Editor\Data\PlaybackEngines\AndroidPlayer\Tools\gradle\lib\gradle-launcher-5.1.1.jar" org.gradle.launcher.GradleMain "-Dorg.gradle.jvmargs=-Xmx4096m" "assembleRelease"
stderr[
编译器 (1.8.0-adoptopenjdk) 中出现异常错误。如果在 Bug Database (http://bugs.java.com) 中没有找到该错误, 请通过 Java Bug 报告页 (http://bugreport.java.com) 建立该 Java 编译器 Bug。请在报告中附上您的程序和以下诊断信息。谢谢。
java.lang.AssertionError: annotationType(): unrecognized Attribute name MODULE (class com.sun.tools.javac.util.UnsharedNameTable$NameImpl)
at com.sun.tools.javac.util.Assert.error(Assert.java:133)
at com.sun.tools.javac.code.TypeAnnotations.annotationType(TypeAnnotations.java:231)
at com.sun.tools.javac.code.TypeAnnotations$TypeAnnotationPositions.separateAnnotationsKinds(TypeAnnotations.java:294)
at com.sun.tools.javac.code.TypeAnnotations$TypeAnnotationPositions.visitVarDef(TypeAnnotations.java:1164)
at com.sun.tools.javac.tree.JCTree$JCVariableDecl.accept(JCTree.java:852)
at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)原因
使用的自定义 gradle (mainTemplate.gradle) 中使用的 tool (4.0.0) 版本高于 unity 自带的 gradle 版本 (5.1.1)
1
2
3
4
5buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:4.0.0' # 对应的 gradle 版本是 6.1.1
**BUILD_SCRIPT_DEPS**}
}gradle tool 版本对应关系 - https://developer.android.com/studio/releases/gradle-plugin?hl=zh-cn#updating-gradle
解决办法: [gradle 升级](#gradle 升级)
android 升级
升级到 32
下载 android-studio-2020.3.1.26-windows.zip
新版 as 编辑器默认不显示 gradle 任务, 需要手动打开
settings -> experimental, 取消勾选 do not build gradle task list during…
更新 sdk,tools
修改 build-tools
- 将
%ANDROID_SDK%\build-tools\32.0.0
目录下的 d8.bat 改成 dx.bat - 将
%ANDROID_SDK%\build-tools\32.0.0\lib
目录下的 d8.jar 改成 dx.jar
- 将
模块升级
将每个模块的 gradle 构建版本都改成新版本
1
2
3
4
5
6
7android {
compileSdkVersion 32
buildToolsVersion '32.0.0'
defaultConfig {
targetSdkVersion 32
}
}如果有引入
androidx.test
单元测试 , 也将版本升级一下单元测试最新版本: https://developer.android.com/jetpack/androidx/releases/test?hl=zh-cn
1
2
3
4
5androidTestImplementation 'androidx.test:core:1.4.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test:runner:1.4.0'
androidTestImplementation 'androidx.test:rules:1.4.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'不然可能出现 构建 app 正常, 执行单元测试用例却失败的情况, 报错:
processdebugandroidtestmanifest manifest merger failed
也可以在 gui 中升级
踩坑
gradle tool 升级报错已损坏
报错: Installed Build Tools revision 32.0.0 is corrupted. Remove and install again using the SDK Manager. 错误
gradle 配置的是 32.0.0
1 | android { |
改成 31.0.0 也报类似的错误
原因是:
The main problem is the two files missing in SDK build tool 31 that are:
- dx.bat
- dx.jar
解决办法:
- 将
%ANDROID_SDK%\build-tools\32.0.0
目录下的 d8.bat 改成 dx.bat - 将
%ANDROID_SDK%\build-tools\32.0.0\lib
目录下的 d8.jar 改成 dx.jar
gradle 升级
- 各版本 gradle 下载地址 - https://services.gradle.org/distributions/
- gradle tool 版本对应关系 - https://developer.android.com/studio/releases/gradle-plugin?hl=zh-cn#updating-gradle
下载 tool 对应的 gradle 版本, 比如: tool 4.0.1 对应的 gradle 是 6.1.1
将 unity 安装目录下的
UNITY_ROOT\Editor\Data\PlaybackEngines\AndroidPlayer\Tools\gradle
的 lib 删了, 然后从gradle-6.1.1-all.zip
文件中解压 lib 丢到该目录下
踩坑
unity 默认版本 低于 tools 版本
自定义配置 tools 版本是 4.0.1, 需要对应的 gradle 版本是 6.1.1, 而 unity 默认版本是 5.1.1
1
classpath 'com.android.tools.build:gradle:4.0.1'
报错
1
2
3
4
5
6
7
8
9
10
11CommandInvokationFailure: Gradle build failed.
D:\unity2018.4.36f1\Editor\Data\PlaybackEngines\AndroidPlayer/Tools\OpenJDK\Windows\bin\java.exe -classpath "D:\unity2018.4.36f1\Editor\Data\PlaybackEngines\AndroidPlayer\Tools\gradle\lib\gradle-launcher-5.1.1.jar" org.gradle.launcher.GradleMain "-Dorg.gradle.jvmargs=-Xmx4096m" "assembleRelease"
stderr[
FAILURE: Build failed with an exception.
* What went wrong:
A problem occurred evaluating root project 'gradleOut'.
> Failed to apply plugin [id 'com.android.internal.version-check']
> Minimum supported Gradle version is 6.1.1. Current version is 5.1.1. If using the gradle wrapper, try editing the distributionUrl in E:\its\tdmj_itc\Temp\gradleOut\gradle\wrapper\gradle-wrapper.properties to gradle-6.1.1-all.zip解决办法
将 unity 默认的 gradle 升级到 6.1.1
aaptOptions.noCompress 数组超出限制
aaptOptions.noCompress 数组的容量限制是 255
对应的 tools 版本是 4.0.1, 对应的 gradle 版本是 6.1.1
1
classpath 'com.android.tools.build:gradle:4.0.1'
报错
1
2
3
4
5
6
7
8
9
10
11
12CommandInvokationFailure: Gradle build failed.
D:/unity_kit/Java/jdk1.8.0_144\bin\java.exe -classpath "D:\unity2018.4.36f1\Editor\Data\PlaybackEngines\AndroidPlayer\Tools\gradle\lib\gradle-launcher-6.1.1.jar" org.gradle.launcher.GradleMain "-Dorg.gradle.jvmargs=-Xmx4096m" "assembleRelease"
stderr[
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':processReleaseResources'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.Workers$ActionFacade
> AAPT2 aapt2-4.0.1-6197926-windows Daemon #0: Unexpected error during link, attempting to stop daemon.
This should not happen under normal circumstances, please file an issue if it does.原因
streamingAssets 下项目下文件数量过多引起的, 导致 unity 默认配置中的
**STREAMING_ASSETS**
这个占位符在 gradle 构建时会全部展开为所有文件1
2
3aaptOptions {
noCompress = ['.unity3d', '.ress', '.resource', '.obb'**STREAMING_ASSETS**]
}**SIGN**构建失败后, 可以查看
UNITY_PROJ\Temp\gradleOut\build.gradle
解决办法
直接去掉
**STREAMING_ASSETS**
, 变为1
2
3aaptOptions {
noCompress = ['.unity3d', '.ress', '.resource', '.obb']
}**SIGN**参考
- https://answers.unity.com/questions/1875624/cant-build-on-android-aapt2-unexpected-error-durin.html
- https://stackoverflow.com/questions/69924552/unity-failed-to-package-after-upgrading-gradle-plug-in-version-to-4-1-0
- Unity3D使用gradle打Android包遇到的aaptOptions.noCompress越界问题及解决方案 - https://www.jianshu.com/p/402d28da05de
aaptOptions.noCompress 配置技巧
aapt官方文档以及网上查到的一些资料都说aaptOptions.noCompress配置的是不压缩资源文件的后缀名,但是使用后缀名来配置有一定的局限性,比如有些文件后缀名相同,但是如果只想将其中几个文件(而不是全部)配成不压缩,再比如有的文件没有后缀名怎么办?
经过实践发现aaptOptions.noCompress机制并不是检查文件后缀名,而是判断文件路径是否以某个字符串结尾,另外一个需要注意的地方是,在做string.EndWith判断之前会将文件路径全部转换为小写,所以aaptOptions.noCompress中的配置项也必须全为小写
android 12 需要明确指定 android:exported
对应的 tools 版本是 4.2.0, 版本 6.7.1
1
classpath 'com.android.tools.build:gradle:4.2.0'
报错
1
2
3
4
5
6
7
8
9
10
11
12CommandInvokationFailure: Gradle build failed.
D:/unity_kit/Java/jdk1.8.0_144\bin\java.exe -classpath "D:\unity2018.4.36f1\Editor\Data\PlaybackEngines\AndroidPlayer\Tools\gradle\lib\gradle-launcher-6.7.1.jar" org.gradle.launcher.GradleMain "-Dorg.gradle.jvmargs=-Xmx4096m" "assembleRelease"
stderr[
E:\its\tdmj_itc\Temp\gradleOut\src\main\AndroidManifest.xml Error:
Apps targeting Android 12 and higher are required to specify an explicit value for `android:exported` when the corresponding component has an intent filter defined. See https://developer.android.com/guide/topics/manifest/activity-element#exported for details.
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':processReleaseMainManifest'.
> Manifest merger failed with multiple errors, see logs解决办法: 所有包含
intent-filter
的service/receiver/activity
都加上android:exported="true"
或android:exported="false"
unity android 配置修改
修改自定义 gradle
tools 版本, 使用的自定义 gradle (mainTemplate.gradle) 中使用的 tool (4.0.0)
1
2
3
4
5buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:4.0.0' # 对应的 gradle 版本是 6.1.1
**BUILD_SCRIPT_DEPS**}
}增加后置任务.
升级 unity 内置 gradle (4.0.1版本) 生成的 aab 文件名为 gradleOut-release.aab, 而 unity 回去找的文件是 gradleOut.aab, 所以会
报错:
FileNotFoundException: Temp\gradleOut\build\outputs\bundle\release\gradleOut.aab does not exist
添加个重命名的任务即可
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17defaultConfig {
// rename aab for unity
tasks.whenTaskAdded { task ->
if (task.name.startsWith("bundle")) {
def renameTaskName = "rename${task.name.capitalize()}Aab"
def flavor = task.name.substring("bundle".length()).uncapitalize()
tasks.create(renameTaskName, Copy) {
def path = "${buildDir}/outputs/bundle/${flavor}/"
from(path)
include "gradleOut-release.aab"
destinationDir file("${buildDir}/outputs/bundle/${flavor}/")
rename "gradleOut-release.aab", "gradleOut.aab"
}
task.finalizedBy(renameTaskName)
}
}
}
修改自定义 AndroidManifest
所有包含
intent-filter
的service/receiver/activity
都加上android:exported="true"
或android:exported="false"
1
2
3
4
5
6
7<activity
android:name="${ps_pkg_path}.MainActivity"
android:label="@string/app_name" android:exported="true">
<intent-filter>
...
</intent-filter>
</activity>
Android 12 启动异常
异常行为可能是 闪退 或者 卡住
unity 社区大多都是报闪退的错误, 参考: https://forum.unity.com/threads/android-12-crash-on-startup.1230936/
原因可能是因为升级了 gradle 导致的 (不升级没办法, 要使用 Android 12 相关 api)
解决办法
简单粗暴升级 unity, 可以升级到 unity 2020.3.31, 这个版本实测过没问题, 过不有在线项目的慎重
经测试, 会卡住流程的是在 csharp 的协程里面的
yield return
语句, 如:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17public class GameMgr : MonoBehaviour {
void Awake() {
Debug.LogFormat("--- ccc 1");
StartCoroutine(Init());
}
IEnumerator Init() {
Debug.LogFormat("--- ccc 2");
yield return StartLuaMain();
}
IEnumerator StartLuaMain() {
Debug.LogFormat("--- ccc 2-1");
yield return 1; // 这里卡住, 不往下走了
Debug.LogFormat("--- ccc 3");
}
}解决办法是需要 Android 的 电话权限, 而且还不能动态申请, 一定要跳转到 app 信息里面手动把 电话权限 打开. 可以在 app 启动
onCreate
的下一帧提示一下去打开 (onCreate 里面不能做一些 ui 操作, 即使在 ui 线程中)```java
@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState); ... // 跳一帧, 检测 Android 12 电话权限 new Handler(Looper.getMainLooper()).post(() -> Tools.adr12CallPermCheck());
}