Unity 应用程序在 Android 上的崩溃处理作为一系列崩溃处理程序工作。链中开头的崩溃处理程序首先接收崩溃,它可以处理崩溃并将其转发到链中的下一个崩溃处理程序。链中崩溃处理程序的顺序由其安装顺序定义。首先安装的崩溃处理程序是最后接收崩溃的处理程序,最后安装的崩溃处理程序是第一个接收崩溃的处理程序。默认情况下,Unity 充当链中的第一个崩溃处理程序。它处理崩溃并将它们转发到链中的下一个崩溃处理程序,默认情况下,该处理程序是 Android 系统崩溃处理程序。
您可以配置 Unity 对崩溃做出不同的反应,并向链中添加您自己的自定义崩溃处理程序。此页面说明如何指定 Unity 用于处理崩溃的方法以及如何创建自定义崩溃处理程序。
如果您不想使用 Unity 的默认崩溃处理行为,则可以使用 -androidChainedSignalHandlerBehavior
命令行参数来更改 Unity 对崩溃的反应方式。此参数采用以下值之一
行为值 | 描述 |
---|---|
legacy |
当发生原生崩溃时,Unity 会包装并抛出该崩溃作为 Java 异常。Unity 不会将崩溃转发到任何已安装的崩溃处理程序或默认系统。 |
disabled |
当发生原生崩溃时,Unity 会忽略它,并且 Android 会将崩溃直接转发到链中的下一个崩溃处理程序。如果安装了自定义崩溃处理程序,则为自定义崩溃处理程序,否则为默认系统。 注意:如果您使用此值,Unity 服务(例如 Unity Cloud Diagnostics)将不再处理崩溃,也不会报告它们。 |
有关如何将此命令行参数传递给 Unity 的信息,请参阅 指定 Unity 启动参数。
本节包含有关如何创建和设置自己的崩溃处理程序的示例。要使其正常工作,您必须不使用 Unity 的旧版崩溃处理行为。有关更多信息,请参阅 指定 Unity 如何处理崩溃。
以下代码示例显示了一个自定义崩溃处理程序。如果您使用 IL2CPPUnity 开发的一种脚本后端,您可以在为某些平台构建项目时将其用作 Mono 的替代方案。 更多信息
请参阅 术语表 脚本后端为 Unity 中的脚本提供支持的框架。根据目标平台的不同,Unity 支持三种不同的脚本后端:Mono、.NET 和 IL2CPP。但是,通用 Windows 平台仅支持两种:.NET 和 IL2CPP。 更多信息
请参阅 术语表,您可以将此示例 cpp
文件直接放入您的 Unity 项目中。然后,Unity 会将其作为 libil2cpp.cpp
的一部分进行编译。如果您使用 MonoUnity 中使用的脚本后端。 更多信息
请参阅 术语表 脚本后端,则必须编译并链接您自己的共享库。有关更多信息,请参阅 为 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 Player 初始化后但在 C# 代码运行之前发生。
以下代码示例显示了如何从 Java 代码调用 InstallCustomSignalHandlers
方法。要将其添加到您的项目中,您可以将其作为 插件在 Unity 之外创建的一组代码,用于在 Unity 中创建功能。在 Unity 中,您可以使用两种类型的插件:托管插件(使用 Visual Studio 等工具创建的托管 .NET 程序集)和原生插件(特定于平台的原生代码库)。 更多信息
请参阅 术语表 安装(请参阅 创建 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();
}
...