Android 上的 Unity 应用程序的崩溃处理以崩溃处理程序链的形式执行。位于链开头的崩溃处理程序首先接收崩溃,它可以处理崩溃并将崩溃转发给链中的下一个崩溃处理程序。链中崩溃处理程序的顺序由它们的安装顺序定义。首先安装的崩溃处理程序是最后一个接收崩溃的处理程序,最后安装的崩溃处理程序是第一个接收崩溃的处理程序。默认情况下,Unity 充当链中的第一个崩溃处理程序。它处理崩溃并将它们转发给链中的下一个崩溃处理程序,即默认情况下的 Android 系统崩溃处理程序。
您可以将 Unity 配置为对崩溃做出不同的反应,还可以将您自己的自定义崩溃处理程序添加到链中。本页介绍如何为 Unity 指定一个方法用于处理崩溃以及如何创建自定义崩溃处理程序。
如果不想采用 Unity 的默认崩溃处理行为,可以使用 -androidChainedSignalHandlerBehavior 命令行参数来更改 Unity 对崩溃的反应方式。此参数采用以下值之一:
| 行为值 | 描述 |
|---|---|
legacy |
发生本机崩溃时,Unity 会将崩溃打包并以 Java 异常的形式抛出。Unity 不会将崩溃转发给任何已安装的崩溃处理程序或默认系统。 |
disabled |
发生本机崩溃时,Unity 会忽略该崩溃,而 Android 会将该崩溃直接转发给链中的下一个崩溃处理程序。下一个崩溃处理程序是自定义崩溃处理程序(如果已安装),否则就是默认系统。 注意:如果使用此值,Unity 服务(如 Unity Cloud Diagnostics)将不再处理崩溃,也不会报告崩溃。 |
有关如何将此命令行参数传递给 Unity 的信息,请参阅指定 Unity 启动参数。
本节包含如何创建和设置您自己的崩溃处理程序的示例。要使此功能正常运行,不得使用 Unity 的旧版崩溃处理行为。有关更多信息,请参阅指定 Unity 处理崩溃的方法。
以下代码示例显示了自定义崩溃处理程序。如果使用 IL2CPP 脚本后端,则可以将此示例 cpp 文件直接放入 Unity 项目中。Unity 随后将其编译为 libil2cpp.cpp 的一部分。如果使用 Mono 脚本后端,则必须编译并链接自己的共享库。有关更多信息,请参阅创建 Android 原生插件。
android_crash_handler.cpp
#include <android/log.h>
#include <jni.h>
#include <signal.h>
struct sigaction s_PreviousHandler;
bool s_SignalHandlerInstalled;
static void MyCustomHandler(int sig, siginfo_t* info, void* ucontext)
{
__android_log_print(ANDROID_LOG_VERBOSE, "CustomCrashHandler", "Handling signal %d", sig);
s_PreviousHandler.sa_sigaction(sig, info, ucontext);
}
extern "C" void InstallCustomSignalHandlers()
{
struct sigaction Action = {};
Action.sa_sigaction = MyCustomHandler;
// Note: Register more signals if you want.
Action.sa_flags = SIGSEGV;
sigaction(SIGSEGV, &Action, &s_PreviousHandler);
s_SignalHandlerInstalled = true;
}
extern "C" JNIEXPORT void Java_com_unity3d_player_UnityPlayerActivity_InstallCustomSignalHandlersFromJava()
{
InstallCustomSignalHandlers();
}
extern "C" void UninstallCustomSignalHandlers()
{
if (s_SignalHandlerInstalled)
{
sigaction(SIGSEGV, &s_PreviousHandler, nullptr);
s_SignalHandlerInstalled = false;
}
}
要安装崩溃处理程序并让 Unity 用它来处理崩溃,请在上述 cpp 文件中调用 InstallCustomSignalHandlers 方法。可以通过 C# 或 Java 代码来执行此操作,但最佳做法是从 Java 调用此方法,因为崩溃可能发生在 Unity 播放器初始化之后,但在 C# 代码运行之前。
以下代码示例展示了如何从 Java 代码调用 InstallCustomSignalHandlers 方法。要将其添加到项目中,您可以将 Java 文件安装为插件(请参阅创建 Java 或 Kotlin 源代码插件),也可以修改导出项目中的现有 Java 文件。
注意:它会根据调用此方法的位置,更改崩溃处理的行为。如果在 Unity 运行时初始化(这是一行包含 mUnityPlayer = new UnityPlayer(this, this); 的代码)之前调用它,则在本机崩溃期间,首先执行 Unity 的崩溃处理程序,然后执行信号处理程序(如果 Unity 转发了信号)。如果在 Unity 运行时初始化后调用 InstallCustomSignalHandlers,则在本机崩溃期间,首先执行处理程序,并由您负责转发信号。
UnityPlayerActivity.java
...
public native void InstallCustomSignalHandlersFromJava();
static
{
System.loadLibrary("il2cpp");
}
// Setup activity layout
@Override protected void onCreate(Bundle savedInstanceState)
{
InstallCustomSignalHandlersFromJava();
...
mUnityPlayer = new UnityPlayer(this, this);
setContentView(mUnityPlayer);
mUnityPlayer.requestFocus();
}
...