# Android 符号

> Generate symbols to help you debug a built Android application.

为了帮助您调试应用程序，Unity 可以生成一个包含符号文件的包，其中包含本机 Unity 库的调试元数据。符号文件包含一个名为符号表 (`.symtab`) 的可执行文件部分，可将活动内存地址转换为可以使用的信息，例如方法名称。转换过程称为符号化。将符号包上传到 Google Play 控制台，即可在 [Android Vitals](https://developer.android.com/topic/performance/vitals) 后台上查看人类可读的堆栈跟踪。

有关可执行文件 (ELF) 部分的更多信息，请参阅 [Wikipedia](https://en.wikipedia.org/wiki/Executable_and_Linkable_Format)。

Unity 为以下库生成符号文件：

* `libmain`：负责初始 Unity 引擎加载逻辑。符号文件已预编译。

* `libunity`：Unity 的引擎代码：

  * 如果禁用 **Strip Engine Code** 属性，则会预编译符号文件。
  * 如果启用了 **Strip Engine Code** 属性，Unity 将在构建过程中编译符号文件。

* `libil2cpp`：包含 C# 脚本：

  * 如果不导出项目，Unity 会在构建过程中编译符号文件。
  * 如果导出项目，Gradle 会编译符号文件。

Gradle 会生成剩余的符号文件。

Unity 根据应用程序构建格式，以两种方式生成符号文件：

* 作为可为 `apk` 或 `aab` 生成的 zip 文件。
* 直接在 `aab` 中嵌入符号文件。Unity 不会将符号文件嵌入到 `apk` 中。

使用 [UserBuildSettings.DebugSymbols.format](ScriptRef:Android.UserBuildSettings.DebugSymbols-format) API 可设置符号包的格式。

## 符号文件类型##types-of-symbol-files

Unity 使用 Gradle 的 [debugSymbolLevel](https://developer.android.com/reference/tools/gradle-api/7.3/com/android/build/api/dsl/Ndk#debugSymbolLevel\(\)) 属性来生成符号文件。符号文件有两种类型：

* 公共：包含符号表部分的小文件。有关更多信息，请参阅[公共符号](#public-symbols)。
* 调试：包含公共符号文件包含的所有内容以及可用于更深入调试的完整调试信息。有关更多信息，请参阅[调试符号](#debugging-symbols)。

使用 [UserBuildSettings.DebugSymbols.level](ScriptRef:Android.UserBuildSettings.DebugSymbols-level) 可生成所需类型的符号文件。

\*\*注意：\*\*默认情况下，Gradle 会生成具有 `.so.sym` 或 `.so.dbg` 扩展名的符号文件。某些数字分发服务无法识别这些扩展名，需要具有 `.so` 扩展名的文件。在这种情况下，请使用 [Unity.Android.Types.DebugSymbolFormat.LegacyExtensions](/engine/6000.0/script-reference/unity-android-types/debug-symbol-format/legacy-extensions.md) API 创建具有 `.so` 扩展名的符号文件。

```
UserBuildSettings.DebugSymbols.format = DebugSymbolFormat.IncludeInBundle | DebugSymbolFormat.Zip | DebugSymbolFormat.LegacyExtensions;
```

### 公共符号##public-symbols

公共符号文件包含将函数地址解析为人类可读字符串的信息。这些文件不包含调试信息。这使得公共符号文件小于[调试符号](#debugging-symbols)文件。

### 调试符号##debugging-symbols

调试符号文件包含完整的调试信息和符号表部分。可使用它：

* 解析堆栈跟踪并调试可为其使用源代码的应用程序。
* 将本机调试器附加到应用程序上并调试代码。

\*\*注意：\*\*如果调试符号不可用，Unity 会在构建时在项目中放置一个[公共符号](#public-symbols)文件。对于 `libmain` 和 `libunity` 库，调试符号不可用，Unity 始终生成公共文件。

### 自定义符号##custom-symbols

可以指示 Unity 将其他符号文件包含进来。如果您使用共享库并希望本地调试器和 Google Play 在应用程序崩溃时解析共享库堆栈跟踪，这将非常有用。

要使 Unity 包含自定义符号文件：

1. 在项目 (Project) 窗口中，选择具有 `.so` 文件扩展名的插件。
2. 在检视面板 (Inspector) 中，找到**平板设置 (Platform settings)** 部分。
3. 将 **CPU** 设置为符号文件兼容的 CPU 架构。
4. 将**共享库类型 (Shared Library Type)** 设置为**符号 (Symbol)**。

Unity 每次生成符号包时都会将其他符号文件添加到符号包中。

如果要使 Unity 包含 C# 脚本中的自定义符号文件，**UnityEditor.Android** 命名空间要包含以下 API 以分别设置 **CPU** 和**共享库类型 (Shared Library Type)**：

* [PluginImporter.SetAndroidCPU](/engine/6000.0/script-reference/unity-editor-android/android-plugin-importer-utilities/set-android-cpu.md)
* [PluginImporter.SetAndroidSharedLibraryType](/engine/6000.0/script-reference/unity-editor-android/android-plugin-importer-utilities/set-android-shared-library-type.md)

\*\*注意：\*\*符号文件名必须与符号文件所对应的共享库的名称匹配。例如，如果共享库名为 **mylibrary.so**，符号文件也必须命名为 **mylibrary.so**。为了避免文件名冲突，符号文件和共享库必须位于单独的目录中。

\*\*重要信息：\*\*确保符号文件是最新的并与包含可执行代码的共享库兼容。否则，本地调试器和 Google Play 将无法解析共享库中代码的堆栈跟踪。


**Frame:**
![](/api/media?file=/engine/6000.0/media/images/android_custom_symbol.png)

## 生成符号包##generating-a-symbols-package

有两种方法可以为应用程序启用符号包生成：

* 通过**构建设置**窗口
* 使用 [UserBuildSettings.DebugSymbols.level](ScriptRef:Android.UserBuildSettings.DebugSymbols-level) 和 [UserBuildSettings.DebugSymbols.format](ScriptRef:Android.UserBuildSettings.DebugSymbols-format) API。

要通过构建设置窗口启用符号包生成，请执行以下操作：

1. 打开构建配置文件 (Build Profiles) 窗口（菜单：**文件 (File)** > **构建配置文件 (Build Profiles)**）。

2. 选择 Android 平台。

3. 将**调试符号 (Debug Symbols)** 设置为以下值之一：

   * [公共](#public-symbols)
   * [调试](#debugging-symbols)

4. 将\*\*符号输出选项 (Symbols output options) \*\*设置为 **.zip**。

启用符号包生成后，构建项目会生成一个包含 `libmain` 和 `libunity` 库符号文件的 `.zip` 文件。如果将[脚本后端](/engine/6000.0/manual/scripting/compilation-and-code-reload/backends.md)设置为 **IL2CPP**，该 `.zip` 还会包含 `libil2cpp` 库的符号文件。Unity 将此符号包放在输出目录中。

如果在 Android 构建设置 (Android Build Settings) 中启用了**导出项目 (Export Project)**，Unity 将不会构建项目。相反，它会导出 Android Studio 项目，为 `libmain` 和 `libunity` 生成符号，并将它们放在输出目录中的 `unityLibrary/symbols/<architecture>/` 中。从 Android Studio 构建导出的项目时，Gradle 会生成 `libil2cpp` 符号文件并将其与 `libmain` 和 `libunity` 符号文件放在 `unityLibrary/symbols/<architecture>/` 目录中。

## 在 Google Play 控制台中使用符号##using-symbols-in-the-google-play-console

### 嵌入式符号##embedded-symbols

如果要生成 Android App Bundle (aab)，可以直接将符号嵌入 `aab` 并将其上传到 Google Play。

\*\*注意：\*\*Unity 不会将符号嵌入到 `apk` 中。在这种情况下，必须单独上传带有符号的 zip 文件。

```
UserBuildSettings.DebugSymbols.level = DebugSymbolLevel.SymbolTable;
UserBuildSettings.DebugSymbols.format = DebugSymbolFormat.IncludeInBundle;
```

### 压缩符号##zipped-symbols

要生成压缩符号包，请使用以下代码：

```
UserBuildSettings.DebugSymbols.level = DebugSymbolLevel.SymbolTable;
UserBuildSettings.DebugSymbols.format = DebugSymbolFormat.Zip | DebugSymbolFormat.LegacyExtensions;
```

将应用程序上传到 Google Play 后，可以上传[公共符号](#public-symbols) zip 包。有关如何执行此操作的更多信息，请参阅 Google 文档：[解混淆或符号化解析崩溃堆栈跟踪](https://support.google.com/googleplay/android-developer/answer/9848633)。

\*\*注意：\*\*Google Play 不会将在上传符号包之前应用程序收到的崩溃符号化。
