(Unity 2019.2) iOS 构建在应用程序被用户终止后 5 秒崩溃
(Unity 2019.2) iOS build crashes 5 seconds after the application is killed by the user
描述
应用程序在被用户终止(即强制终止应用程序)后 2~5 秒出现崩溃。这仅发生在 iOS 构建在多个统一版本上(请参阅下面的详细信息)。
大多数崩溃报告都没有到达 Crashlytics。控制台上很少发生崩溃,尽管我们每天都在不断重现此错误。
Android 构建不会出现相同的错误。
重现步骤
- 打开游戏
- 等待加载场景即将完成或游戏场景完全加载
- 终止应用程序
- 等待2~5秒,查看崩溃报告window
- 再生率:80%
- 用于测试的设备:iPhoneSE,iPhone7,iPhone8,iPadMini 4
- 还观察到崩溃:iPhone XS,iPhone XR
附加信息
- 问题是 iOS 具体的。我们在 Android 上有相同的构建,工作没有问题。
- 在大多数情况下,Crashlytics 不会捕获崩溃报告(请参阅下面的一些崩溃)。
- 崩溃仅发生在加载的最后一步,此时外部 SDK 正在初始化。
- 在 TestFlight 上,几乎所有构建的崩溃计数都是 0,包括用户报告崩溃的构建。
- 使用调用 Unity 的 Application.Quit() 方法的调试按钮不会导致应用程序崩溃,即使它需要一段时间才能关闭。
- 崩溃似乎对 OS 版本和 iOS 设备是不变的。
技术资料
- Unity版本:2019.2.17f1。也转载了2019.2.0f1和2019.3.10f1.
- 外部插件是 listed here。
- 崩溃报告
探索
这是迄今为止所有未成功解决方案尝试的列表:
- 删除 GameAnalytics 插件
- 删除 IronSource 插件
- 移除 UnityIAP 插件
- Workaround 后处理 iOS
- 将最低 OS 版本设置为 9.0
- 评论所有 OnApplicationPause/Quit 实现(包括插件)
- 启用位码
解决方案
描述:一般问题是当应用程序完成时,在 iOS 上有任何代码块阻塞主线程(请参阅 this document想要查询更多的信息)。在我们的例子中,这是由于玩家终止应用程序时正在进行的请求而发生的。当我们在应用程序终止时(使用 Dispose()
方法)将播放器进度保存在服务器上时,请求阻塞了主线程,导致崩溃。解决方案是删除这个特定的保存。我们测试了包含此修复程序的构建,到目前为止,我们在加载游戏场景后 20 次尝试终止游戏时没有出现崩溃。我们之前没有考虑过这个问题,因为这段代码自 2019 年 8 月以来一直存在,从那以后就没有人碰过它。这个问题是2020年2月才开始出现的。
更多信息:由于该段有问题的代码自 2019 年 8 月起就出现在项目中,并且问题仅在 2020 年 2 月才开始出现,因此 可能 iOS 版本与它有关。我们还没有调查变更日志,但目前出现崩溃的最旧 iOS 版本是 iOS 13.2,于 2019 年 10 月 28 日发布。
另一种可能是我们后端代码的某些更改导致请求挂起。当我们使用 BestHTTP 时,默认情况下所有请求都会在应用程序终止时中止。我们尚未调查 Dispose
与 OnDisable/OnApplicationQuit
的执行顺序是否可能是问题所在。此外,默认情况下,BestHTTP 在应用程序退出期间中止的请求仍会调用回调。在我们的例子中,那个 Save Player 的回调是 null
,所以这可能不是问题。
相关崩溃:我们在加载场景中仍然面临一些崩溃问题。据我们所见,当有请求时,它们就会发生。这些问题的重现率远低于Game Scene上的问题
提示:我们很难检索到 Crashlytics 上的日志,因为其中大部分都没有发送。以下是如何从 iOS 设备本身检索日志的分步说明:
- 在您的iPhone/iPad设备上打开设置应用程序
- 转到隐私(出现在电池下方iOS 13)
- 滚动到底部并打开 分析和改进
- 打开分析数据
- 查找所需应用程序的日志
描述
应用程序在被用户终止(即强制终止应用程序)后 2~5 秒出现崩溃。这仅发生在 iOS 构建在多个统一版本上(请参阅下面的详细信息)。 大多数崩溃报告都没有到达 Crashlytics。控制台上很少发生崩溃,尽管我们每天都在不断重现此错误。 Android 构建不会出现相同的错误。
重现步骤
- 打开游戏
- 等待加载场景即将完成或游戏场景完全加载
- 终止应用程序
- 等待2~5秒,查看崩溃报告window
- 再生率:80%
- 用于测试的设备:iPhoneSE,iPhone7,iPhone8,iPadMini 4
- 还观察到崩溃:iPhone XS,iPhone XR
附加信息
- 问题是 iOS 具体的。我们在 Android 上有相同的构建,工作没有问题。
- 在大多数情况下,Crashlytics 不会捕获崩溃报告(请参阅下面的一些崩溃)。
- 崩溃仅发生在加载的最后一步,此时外部 SDK 正在初始化。
- 在 TestFlight 上,几乎所有构建的崩溃计数都是 0,包括用户报告崩溃的构建。
- 使用调用 Unity 的 Application.Quit() 方法的调试按钮不会导致应用程序崩溃,即使它需要一段时间才能关闭。
- 崩溃似乎对 OS 版本和 iOS 设备是不变的。
技术资料
- Unity版本:2019.2.17f1。也转载了2019.2.0f1和2019.3.10f1.
- 外部插件是 listed here。
- 崩溃报告
探索
这是迄今为止所有未成功解决方案尝试的列表:
- 删除 GameAnalytics 插件
- 删除 IronSource 插件
- 移除 UnityIAP 插件
- Workaround 后处理 iOS
- 将最低 OS 版本设置为 9.0
- 评论所有 OnApplicationPause/Quit 实现(包括插件)
- 启用位码
解决方案
描述:一般问题是当应用程序完成时,在 iOS 上有任何代码块阻塞主线程(请参阅 this document想要查询更多的信息)。在我们的例子中,这是由于玩家终止应用程序时正在进行的请求而发生的。当我们在应用程序终止时(使用 Dispose()
方法)将播放器进度保存在服务器上时,请求阻塞了主线程,导致崩溃。解决方案是删除这个特定的保存。我们测试了包含此修复程序的构建,到目前为止,我们在加载游戏场景后 20 次尝试终止游戏时没有出现崩溃。我们之前没有考虑过这个问题,因为这段代码自 2019 年 8 月以来一直存在,从那以后就没有人碰过它。这个问题是2020年2月才开始出现的。
更多信息:由于该段有问题的代码自 2019 年 8 月起就出现在项目中,并且问题仅在 2020 年 2 月才开始出现,因此 可能 iOS 版本与它有关。我们还没有调查变更日志,但目前出现崩溃的最旧 iOS 版本是 iOS 13.2,于 2019 年 10 月 28 日发布。
另一种可能是我们后端代码的某些更改导致请求挂起。当我们使用 BestHTTP 时,默认情况下所有请求都会在应用程序终止时中止。我们尚未调查 Dispose
与 OnDisable/OnApplicationQuit
的执行顺序是否可能是问题所在。此外,默认情况下,BestHTTP 在应用程序退出期间中止的请求仍会调用回调。在我们的例子中,那个 Save Player 的回调是 null
,所以这可能不是问题。
相关崩溃:我们在加载场景中仍然面临一些崩溃问题。据我们所见,当有请求时,它们就会发生。这些问题的重现率远低于Game Scene上的问题
提示:我们很难检索到 Crashlytics 上的日志,因为其中大部分都没有发送。以下是如何从 iOS 设备本身检索日志的分步说明:
- 在您的iPhone/iPad设备上打开设置应用程序
- 转到隐私(出现在电池下方iOS 13)
- 滚动到底部并打开 分析和改进
- 打开分析数据
- 查找所需应用程序的日志