# 处理 Android 崩溃

> Understand the chain of crash handlers that defines what happens if your application crashes.

Android 上的 Unity 应用程序的崩溃处理以崩溃处理程序链的形式执行。位于链开头的崩溃处理程序首先接收崩溃，它可以处理崩溃并将崩溃转发给链中的下一个崩溃处理程序。链中崩溃处理程序的顺序由它们的安装顺序定义。首先安装的崩溃处理程序是最后一个接收崩溃的处理程序，最后安装的崩溃处理程序是第一个接收崩溃的处理程序。默认情况下，Unity 充当链中的第一个崩溃处理程序。它处理崩溃并将它们转发给链中的下一个崩溃处理程序，即默认情况下的 Android 系统崩溃处理程序。

您可以将 Unity 配置为对崩溃做出不同的反应，还可以将您自己的自定义崩溃处理程序添加到链中。本页介绍如何为 Unity 指定一个方法用于处理崩溃以及如何创建自定义崩溃处理程序。

## 指定 Unity 处理崩溃的方法##specify-how-unity-handles-crashes

如果不想采用 Unity 的默认崩溃处理行为，可以使用 `-androidChainedSignalHandlerBehavior` 命令行参数来更改 Unity 对崩溃的反应方式。此参数采用以下值之一：

| **行为值**    | **描述**                                                                                                                                                      |
| ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `legacy`   | 发生本机崩溃时，Unity 会将崩溃打包并以 Java 异常的形式抛出。Unity 不会将崩溃转发给任何已安装的崩溃处理程序或默认系统。                                                                                        |
| `disabled` | 发生本机崩溃时，Unity 会忽略该崩溃，而 Android 会将该崩溃直接转发给链中的下一个崩溃处理程序。下一个崩溃处理程序是自定义崩溃处理程序（如果已安装），否则就是默认系统。**注意**：如果使用此值，Unity 服务（如 Unity Cloud Diagnostics）将不再处理崩溃，也不会报告崩溃。 |

有关如何将此命令行参数传递给 Unity 的信息，请参阅[指定 Unity 启动参数](/engine/6000.0/manual/platform-specific/android/developing/application-entries/activity/unity-player-activity/custom-activity-command-line.md)。

## 创建和设置自定义崩溃处理程序##create-and-setup-a-custom-crash-handler

本节包含如何创建和设置您自己的崩溃处理程序的示例。要使此功能正常运行，不得使用 Unity 的旧版崩溃处理行为。有关更多信息，请参阅[指定 Unity 处理崩溃的方法](#specify-how-unity-handles-crashes)。

### 创建崩溃处理程序##create-a-crash-handler

以下代码示例显示了自定义崩溃处理程序。如果使用 [IL2CPP](/engine/6000.0/manual/scripting/compilation-and-code-reload/backends/il2cpp.md) [脚本后端](/engine/6000.0/manual/scripting/compilation-and-code-reload/backends.md)，则可以将此示例 `cpp` 文件直接放入 Unity 项目中。Unity 随后将其编译为 `libil2cpp.cpp` 的一部分。如果使用 [Mono](/engine/6000.0/manual/scripting/compilation-and-code-reload/backends/mono.md) 脚本后端，则必须编译并链接自己的共享库。有关更多信息，请参阅[创建 Android 原生插件](/engine/6000.0/manual/platform-specific/android/developing/plugins-for/plugin-types/native-plugins/create.md)。

**android\_crash\_handler.cpp**

```C++
#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;
  }
}
```

### 安装崩溃处理程序##install-the-crash-handler

要安装崩溃处理程序并让 Unity 用它来处理崩溃，请在上述 `cpp` 文件中调用 `InstallCustomSignalHandlers` 方法。可以通过 [C#](/engine/6000.0/manual/platform-specific/android/developing/plugins-for/plugin-types/native-plugins/call.md) 或 Java 代码来执行此操作，但最佳做法是从 Java 调用此方法，因为崩溃可能发生在 Unity 播放器初始化之后，但在 C# 代码运行之前。

以下代码示例展示了如何从 Java 代码调用 `InstallCustomSignalHandlers` 方法。要将其添加到项目中，您可以将 Java 文件安装为插件（请参阅[创建 Java 或 Kotlin 源代码插件](/engine/6000.0/manual/platform-specific/android/developing/plugins-for/plugin-types/java-source-plugins.md#CreateSourcePlugins)），也可以修改[导出项目](/engine/6000.0/manual/platform-specific/android/building-and-delivering/export-process.md)中的现有 Java 文件。

**注意**：它会根据调用此方法的位置，更改崩溃处理的行为。如果在 Unity 运行时初始化（这是一行包含 `mUnityPlayer = new UnityPlayer(this, this);` 的代码）之前调用它，则在本机崩溃期间，首先执行 Unity 的崩溃处理程序，然后执行信号处理程序（如果 Unity 转发了信号）。如果在 Unity 运行时初始化后调用 `InstallCustomSignalHandlers`，则在本机崩溃期间，首先执行处理程序，并由您负责转发信号。

**UnityPlayerActivity.java**

```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();
  }
...
```
