title: unity-android和gradle升级
categories: Unity3d
tags: [unity, android, gradle, 升级]
date: 2022-01-23 15:33:10
comments: false
mathjax: true
toc: true
unity-android和gradle升级, 使用的 unity 版本是 2018.4.36f1 (LTS)
前篇
适配 android 11,12 的需要
sdk 升级到 最新版本后 unity 打包问题
报错无法识别的属性名模块: unrecognized Attribute name MODULE
-
完整报错
CommandInvokationFailure: 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)
buildscript { 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 构建版本都改成新版本
android { compileSdkVersion 32 buildToolsVersion '32.0.0' defaultConfig { targetSdkVersion 32 } }
-
如果有引入
androidx.test
单元测试 , 也将版本升级一下单元测试最新版本: https://developer.android.com/jetpack/androidx/releases/test?hl=zh-cn
androidTestImplementation '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
android {
compileSdkVersion 32
buildToolsVersion '32.0.0'
defaultConfig {
minSdkVersion 19
targetSdkVersion 32
}
}
改成 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
参考: https://stackoverflow.com/questions/68387270/android-studio-error-installed-build-tools-revision-31-0-0-is-corrupted
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
classpath 'com.android.tools.build:gradle:4.0.1'
-
报错
CommandInvokationFailure: 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
classpath 'com.android.tools.build:gradle:4.0.1'
-
报错
CommandInvokationFailure: 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 构建时会全部展开为所有文件aaptOptions { noCompress = ['.unity3d', '.ress', '.resource', '.obb'**STREAMING_ASSETS**] }**SIGN**
-
构建失败后, 可以查看
UNITY_PROJ\Temp\gradleOut\build.gradle
-
-
解决办法
直接去掉
**STREAMING_ASSETS**
, 变为aaptOptions { 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
classpath 'com.android.tools.build:gradle:4.2.0'
-
报错
CommandInvokationFailure: 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)
buildscript { 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
添加个重命名的任务即可
defaultConfig { // 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) } } }
- 参考: https://stackoverflow.com/questions/66997991/filenotfoundexception-temp-gradleout-build-outputs-bundle-release-gradleout-aab?rq=1
-
-
修改自定义 AndroidManifest
所有包含
intent-filter
的service/receiver/activity
都加上android:exported="true"
或android:exported="false"
<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
语句, 如:public 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 线程中)@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... // 跳一帧, 检测 Android 12 电话权限 new Handler(Looper.getMainLooper()).post(() -> Tools.adr12CallPermCheck()); }
-