unity-android和gradle升级


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

  1. 下载 android-studio-2020.3.1.26-windows.zip

    新版 as 编辑器默认不显示 gradle 任务, 需要手动打开

    settings -> experimental, 取消勾选 do not build gradle task list during…

  2. 更新 sdk,tools

  3. 修改 build-tools

    1. %ANDROID_SDK%\build-tools\32.0.0 目录下的 d8.bat 改成 dx.bat
    2. %ANDROID_SDK%\build-tools\32.0.0\lib 目录下的 d8.jar 改成 dx.jar

模块升级
  1. 将每个模块的 gradle 构建版本都改成新版本

    android {
        compileSdkVersion 32
        buildToolsVersion '32.0.0'
        defaultConfig {
            targetSdkVersion 32
        }
    }
    
  2. 如果有引入 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:

  1. dx.bat
  2. dx.jar

解决办法:

  1. %ANDROID_SDK%\build-tools\32.0.0 目录下的 d8.bat 改成 dx.bat
  2. %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
  1. 下载 tool 对应的 gradle 版本, 比如: tool 4.0.1 对应的 gradle 是 6.1.1

  2. 将 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-filterservice/receiver/activity 都加上 android:exported="true"android:exported="false"


unity android 配置修改

  1. 修改自定义 gradle

    1. 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**}
      }
      
    2. 增加后置任务.

      升级 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
  2. 修改自定义 AndroidManifest

    所有包含 intent-filterservice/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)

  1. 解决办法

    1. 简单粗暴升级 unity, 可以升级到 unity 2020.3.31, 这个版本实测过没问题, 过不有在线项目的慎重

    2. 经测试, 会卡住流程的是在 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());
      }
      
      
      
      

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蝶泳奈何桥.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值