在 Windows 计算机上设置 Android 游戏开发扩展并在 Android 设备或模拟器上运行示例 Visual Studio C++ 项目。
按照本节中的步骤准备您的 Windows 计算机以安装扩展程序:
下载并安装 Visual Studio 的受支持版本之一:
下载并安装 .NET Core SDK 2.2。
Android Studio 3.5 或更高版本是可选的,但可以代替 Android 游戏开发扩展来安装 Android SDK 和 NDK。
按照本节中的步骤下载并安装 Android 游戏开发扩展:
关闭 Visual Studio 的所有实例。
从下载页面下载最新的扩展安装程序和示例 。
从您的下载位置,双击安装程序。安装程序需要几分钟才能完成。
如果您安装了多个版本的 Visual Studio,请选择您希望为其安装扩展的版本。
单击完成以完成安装。
您可以使用 Android Studio 或 Android Game Development Extension安装 Android SDK 和 Android Native Development Kit (NDK) 。要从扩展安装 SDK 和 NDK,请使用SDK 管理器,它位于 Visual Studio 的扩展工具栏中。
安装 NDK 时,请确保使用NDK(并排)复选框,以便扩展程序可以找到它。您必须安装扩展支持的 NDK 版本(请参阅NDK 修订历史记录)。
要将 SDK 安装到与默认位置不同的位置, ANDROID_SDK_ROOT
请在您的计算机上设置环境变量:
Environment Variables
.ANDROID_SDK_ROOT
。无法使用 SDK 管理器窗口修改 SDK 的位置,因为此环境变量是 SDK 位置的唯一真实来源。
按照本节中的步骤在模拟器中运行 Teapot 示例,然后在物理 Android 设备上运行。
图 1. Android 平台属性 图 2. Android 打包属性
如果 Visual Studio 尚未运行,请启动它。
将示例 zip 文件解压缩到您选择的目录中。包括以下示例:
打开示例目录。选择文件 > 打开 > 项目/解决方案并导航到Teapot.sln
.
选择安卓平台:
示例中已经配置了两个 Android 平台(您可以稍后添加更多 Android 平台)。
注意:典型的模拟器映像使用 x86 或 x86_64 ABI。
确保示例项目配置了 Android SDK 和 NDK 属性:
在解决方案资源管理器中,右键单击GameApplication并选择 Properties。
选择常规属性选项卡并找到适用于 Android 的平台 属性。
您可以从此选项卡更改输出 APK 名称和目录。请注意,一些 Android 配置属性在属性页中定义并传递给 Gradle。例如,APK 名称属性 MSBUILD_ANDROID_OUTPUT_APK_NAME
将此名称传递给应用程序build.gradle
文件。
从 Visual Studio 的扩展工具栏中启动 AVD Manager。配置一个虚拟设备,然后 在 Android Studio 模拟器中运行它。
注意:当 Android Studio 打开时,使用 Visual Studio 进行调试会中断。
通过单击Android 虚拟设备管理器中的运行按钮来启动虚拟设备。
在 Visual Studio 中,虚拟设备类型应显示在“开始调试”工具栏按钮旁边 。单击Start Debugging在设备上启动 Teapot 示例应用程序。调试器可能需要一些时间才能附加到应用程序。您可以通过在茶壶上拖动光标来旋转茶壶。
要在物理 Android 设备上运行示例,您可能需要在项目中创建一个新的 Android 平台。该平台必须与设备的架构相匹配。要创建新平台,请在 Visual Studio 中执行以下操作:
为新平台键入以下内容之一:
在Copy settings from框中,选择None。
使用 USB 数据线将 Android 设备连接到您的计算机。设备类型应显示在 Start Debugging工具栏按钮旁边。
如果未显示设备类型,请检查以下内容:
单击开始调试工具栏按钮以在设备上启动示例茶壶应用程序。调试器可能需要一些时间才能附加到应用程序。连接后,您可以通过在茶壶上拖动手指来旋转茶壶。
以下是有关 Android 游戏开发扩展的一些常见问题。
您可以使用Android 游戏开发扩展工具栏中的打开日志图标 打开插件的日志文件。
该插件使用以下逻辑查找 SDK 的位置:
public static string GetAndroidSdk() =>
Environment.GetEnvironmentVariable("ANDROID_SDK_ROOT") ??
Environment.GetEnvironmentVariable("LocalAppData").Resolve(@"Android\Sdk");
该插件使用以下环境变量:
ANDROID_SDK_ROOT
ANDROID_SDK_HOME
TEMP
GOOGLE_ANDROID_LOG_DIR
要将您自己的项目与扩展一起使用,您必须根据项目配置指南进行配置。
配置项目以使用 Android 游戏开发扩展。
Android 游戏开发扩展调用 MSBuild 将 C/C++ 源代码构建到共享库 ( .so
) 和静态库 ( .a
) 中。作为构建过程的一部分,自定义 MSBuild 任务调用 Gradle 来编译 Java 和 Kotlin 源代码、打包资产并生成用于部署的 APK 文件。配置项目时,必须确保 MSBuild 具有为 Android 平台构建所需的信息。
一个典型的 Android 项目是使用 Gradle 构建的,其中项目内的本机代码由运行CMake或 ndk-build的 Gradle pass 构建。使用 Visual Studio 的 Android 游戏开发扩展,构建过程是相反的。现在 MSBuild 是构建过程的起点。所有 C/C++ 源代码均由 MSBuild 首先构建,用于作为扩展的一部分安装在您的系统上的新 Android 平台(例如,“Android x86_64”)。MSBuild 然后调用 Gradle 将包含 C/C++ 逻辑的共享库文件打包到 APK 中。
您应该首先在 CMake 中复制项目的现有构建逻辑,或者在 MSBuild 中复制 ndk-build。将目标平台设置为以下内容:
这些平台都是由 Android Game Development Extension 提供的。
虽然茶壶示例项目包含 Android 平台,但您必须手动将 Android 平台添加到现有项目中。要添加新平台,请在 Visual Studio 中执行以下操作:
为新平台键入以下内容之一:
在Copy settings from框中,选择None。确保您启用 了创建新项目平台。
选择Add > New Item > Visual C++ > Android > Android APK并单击 Add。在以下对话框中配置 Android 应用程序。
MSBuild 无法调用 Gradle,除非它知道 Gradle 项目的位置。使用Gradle Build Directory属性设置此位置,如图 1 所示。
此外,设置Application Module、Application Variant和APK Name属性(如上图所示),以便 MSBuild 知道要构建什么。
settings.gradle
文件中设置的主要项目。它通常app
用于直接使用 Android Studio 创建的项目。$(Configuration)
.MSBUILD_ANDROID_OUTPUT_APK_NAME
下一节中的属性)。在构建期间,MSBuild 将以下信息作为项目属性传递给 Gradle 脚本。更改项目的现有构建脚本(通常命名为build.gradle
)以读取这些属性。
MSBUILD_MIN_SDK_VERSION
:构建 APK 的最低 SDK 版本。在图 2 所示的项目属性页面上的最低 Android SDK 版本框中设置此值。
Gradle 构建脚本应设置minSdkVersion
为此值,如下所示。
android { // ... defaultConfig { applicationId "com.yourcompany.yourapp" minSdkVersion MSBUILD_MIN_SDK_VERSION // ... } // ... }
MSBUILD_ANDROID_OUTPUT_APK_NAME
:Gradle 构建的 APK 的预期名称。Android 游戏开发扩展将查找与此名称匹配的 APK,然后将其部署到连接的设备(用于调试和分析)。在图 3 所示的项目属性页面的APK Name框中设置此值。
Gradle 构建脚本必须尊重此属性。例如,以下示例将所有变体的输出 APK 名称设置为 MSBuild 选择的名称。
android { // ... applicationVariants.all { variant -> variant.outputs.all { outputFileName = MSBUILD_ANDROID_OUTPUT_APK_NAME } } // ... }
MSBUILD_JNI_LIBS_SRC_DIR
: 包含由 MSBuild 构建的共享库(.so
文件)的目录。在项目属性页面的输出目录框中设置此值, 如下所示。默认情况下,该值是 Visual Studio 项目的输出目录属性,如图 4 所示。
Gradle 应将共享库文件打包到 APK 内的此文件夹中,以便 Android 应用程序在运行时加载它们。
android { // ... sourceSets { main { jniLibs.srcDirs += [MSBUILD_JNI_LIBS_SRC_DIR] } } // ... }
此外,由于任何 C/C++ 代码现在都是由 MSBuild 构建的,因此请删除 externalNativeBuild
Gradle 构建脚本中的部分。这些部分用于调用 CMake 或 ndk-build 来编译您的 C/C++ 代码,但不再需要。
MSBUILD_NDK_VERSION
:用于构建项目的 NDK 版本。在项目属性页面的Android NDK 版本框中设置此值,如图 5 所示。
Gradle 构建脚本应设置ndkVersion
为此值,如下所示:
android { // ... ndkVersion MSBUILD_NDK_VERSION // ... }
有关更多信息,请参阅 Android Studio 主题 安装和配置 NDK 和 CMake。
//
使用 Android 游戏开发扩展时,使用 Visual Studio 调试器 (LLDB) 调试您的项目。
在运行调试器之前,您必须能够在 Android 上构建、部署和运行您的游戏。有关详细信息,请参阅运行示例部分。
一旦你确定你可以在没有调试器的情况下运行你的游戏,你可以通过按F5或选择调试菜单中的开始调试项目来使用调试器。当调试器附加到游戏时,您应该会看到一个对话框。
启动调试器需要 10 秒到 1 分钟或更长时间,具体取决于应用程序的大小和启动时需要加载的符号数量。首次连接到新设备时需要更多时间,因为调试器必须从设备下载一些 Android 库到主机。如果您在使用新设备的前几次尝试中花费的时间超过 1 分钟,请考虑取消调试会话,然后重新启动它。
当您以这种方式运行调试器时,游戏将以等待调试器模式启动,并且在调试器连接之前不会执行任何游戏代码。这使您还可以调试游戏的初始化部分。
您可以通过阅读Visual Studio 文档找到有关特定 Visual Studio 调试器功能的更多信息。
如果要调试已在物理或虚拟设备上运行的游戏,可以将调试器附加到 Visual Studio 中的进程。
在 Visual Studio 中,确保 Android 解决方案已打开,并且:
在调试会话处于活动状态时,使用 Visual Studio 的命令行窗口运行 LLDB.Shell 命令。
命令格式:
LLDB.Shell [command]
例子:
>LLDB.Shell expr myIntVariable = 9
Status: Success
Output Message:
(int) $2 = 9
警告:某些 shell 命令可能会导致 Visual Studio 与 LLDB 不同步并出现异常行为。
您可以使用格式说明符更改值在Autos、 Locals、Watch和变量DataTip窗口中显示的格式。
格式说明符位于表达式的末尾。它们以逗号开头,后跟一个短字符串。例如, 表达式,x
中的说明符会将myInt格式化为小写十六进制。_myInt,x
通过将格式说明符添加到 Natvis 表达式中,可以直接在Watch窗口或 Autos、Locals和DataTip窗口中使用格式说明符。有关详细信息,请参阅Natvis。
支持说明符列表
格式名称 | 说明符 | 描述 |
---|---|---|
布尔值 | 乙 | 将此显示为真/假布尔值,使用习惯规则,即 0 为假,其他一切为真 |
二进制 | b | 将其显示为一系列位 |
二进制,无前导 0b | bb | 将其显示为不带 0b 前缀的位序列 |
字节 | 是的 | 显示字节,但也尝试将它们显示为 ASCII 字符, 例如 (int *) c.sp.x = 50 f8 bf 5f ff 7f 00 00 P.._.... |
ASCII 字节 | 是 | 显示字节,但也尝试将它们显示为 ASCII 字符, 例如 (int *) c.sp.x = 50 f8 bf 5f ff 7f 00 00 P.._.... |
特点 | C | 将字节显示为 ASCII 字符, 例如 (int *) c.sp.x = P\xf8\xbf_\xff\x7f\0\0 |
可打印字符 | C | 将字节显示为可打印的 ASCII 字符, 例如 (int *) c.sp.x = P.._.... |
复数浮点数 | F | 将此值解释为复数浮点数的实部和虚部, 例如 (int *) c.sp.x = 2.76658e+19 + 4.59163e-41i |
十进制 | d, 我 | 将此显示为有符号整数(这不执行强制转换,它只是将字节显示为带符号的整数) |
枚举 | E,en | 将此显示为枚举,如果可用则打印值的名称,否则打印整数值, 例如 (枚举 enumType) val_type = eValue2 |
十六进制 - 小写 | x, h | 以小写十六进制表示法显示(这不执行强制转换,它只是将字节显示为十六进制) |
十六进制 - 大写 | X, H | 以大写十六进制表示法显示(这不执行强制转换,它只是将字节显示为十六进制) |
十六进制 - 小写,无前导 0x | xb, 血红蛋白 | 以不带 0x 前缀的小写十六进制表示法显示(这不执行强制转换,它只是将字节显示为十六进制) |
十六进制 - 大写,没有前导 0x | Xb,血红蛋白 | 以不带 0x 前缀的大写十六进制表示法显示(这不执行强制转换,它只是将字节显示为十六进制) |
漂浮 | F | 将其显示为浮点数(这不执行强制转换,它只是将字节解释为 IEEE754 浮点值) |
八进制 | ○ | 用八进制表示 |
操作系统类型 | ○ | 将其显示为 MacOS OSType, 例如 (浮点数)x = '\n\x1f\xd7\n' |
字符串 - C 字符串 | s | 将其显示为以 0 结尾的 C 字符串, 例如 “你好世界” |
string - C 字符串,不带引号 | 某人 | 将其显示为不带引号的以 0 结尾的 C 字符串, 例如 hello world |
字符串 - UTF-8 | s8 | 将其显示为以 0 结尾的 UTF-8 字符串, 例如 u8"你好世界☕" |
字符串 - UTF-8,无引号 | s8b | 将其显示为不带引号的以 0 结尾的 UTF-8 字符串, 例如 你好世界☕ |
字符串 - UTF-16 | 苏 | 将其显示为以 0 结尾的 UTF-16 字符串, 例如 你“你好世界☕” |
字符串 - UTF-16,无引号 | 子 | 将其显示为不带引号的以 0 结尾的 UTF-16 字符串, 例如 你好世界☕ |
字符串 - UTF-32 | s32 | 将其显示为以 0 结尾的 UTF-32 字符串, 例如 U“你好世界☕” |
字符串 - UTF-32,无引号 | s32b | 将其显示为不带引号的以 0 结尾的 UTF-32 字符串, 例如 你好世界☕ |
unicode16 | ü | 将其显示为 UTF-16 字符, 例如 (浮点数)x = 0xd70a 0x411f |
unicode32 | U32 | 将其显示为 UTF-32 字符, 例如 (浮点数)x = 0x411fd70a |
无符号十进制 | 你 | 将其显示为无符号整数(这不执行强制转换,它只是将字节显示为无符号整数) |
指针 | p | 将其显示为本机指针(除非这确实是一个指针,否则结果地址可能无效) |
复整数 | 我 | 将此值解释为复整数的实部和虚部, 例如 (int *) 指针 = 1048960 + 1i |
字符数组 | 一个 | 将其显示为字符数组, 例如 (char) *c.sp.z = {X} |
生的 | ! | 原始格式,忽略任何数据类型视图自定义 |
Natvis 框架允许您自定义 Visual Studio 在调试器变量窗口中显示本机类型的方式。例如,使用 Natvis 自定义Watch、Locals和Data Tips窗口的显示。
Natvis 功能默认启用,但可以通过将Tools > Options > Android Game Development Extension > Natvis 标志设置为Disabled从 Visual Studio 禁用。
加载 Natvis 文件
Visual Studio 从下面列出的三个位置加载 Natvis 文件,并在您每次启动调试会话时重新加载它们。文件必须符合 Visual Studio 2017 Natvis 架构。
.natvis
作为已加载项目或顶级解决方案项的一部分的文件。%USERPROFILE%\Documents\Visual Studio 2017\Visualizers
)%VSINSTALLDIR%\Common7\Packages\Debugger\Visualizers
)重新加载 Natvis 文件
.natvisreload
在调试会话期间通过在命令窗口或监视窗口中进行评估来重新加载 Natvis 文件。
示例 Natvis 文件
此示例 Natvis 文件包含当前支持的所有标记和属性。
"1.0"
encoding="utf-8"?>
xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
Name="demo::Vector<*>">
Name="MySimilarVectorType<*>"/>
Optional="true" Usage="Minimal">ptr
Condition="_size == 0" Optional="true">()
Condition="_size == 1">(x={_items[0]})
Condition="_size == 2">(x={_items[0]}, y={_items[1]})
Condition="_size == 3">(x={_items[0]}, y={_items[1]}, z={_items[2]})
[Size={_size,x}] (x={_items[0]}, y={_items[1]}, z={_items[2]}, ...)
Condition="true" Optional="true">_stringViewText
HideRawView="false">
- Name="X" Condition="_size < 4 && _size >= 1" Optional="true">_items[0]
- Name="Y" Condition="_size < 4 && _size >= 2" Optional="true">_items[1]
- Name="Z" Condition="_size < 4 && _size >= 3" Optional="true">_items[2]
Condition="_size >= 4" Optional="true">
Condition="true" Optional="true">_size
Condition="true">_items
Condition="true" Optional="true">
Condition="true" Optional="true">_listSize
Condition="true">_list[%i]
Condition="true" Optional="true">
Optional="true">_listSize
_head
_next
_value
Condition="true" Optional="true">_childVar
Name="[Size]" Condition="true" Optional="true">
_size
HideRawView="true">
Condition="true" Optional="true">
_treeSize
_head
_left
_right
_value
- Name="[Hex Dump at {_index,x}]">myInt[_index],x
创作 Natvis 文件
Visual Studio 支持创作您自己的 Natvis 文件。有关自定义调试器变量窗口的更多信息,请参阅 MSDN {: external}。
调试 Natvis 文件
在某些情况下,错误将显示为变量的值(例如在Auto、Watch等窗口中)。例如:
您可以通过GoogleAndroid.log
从 Android 游戏开发扩展工具栏中打开文件来访问有关错误的更多详细信息。
已知限制
如果您的标签或属性未在上面的示例文件中列出,则它目前不受支持。Visual Studio 会忽略不受支持的标记和属性,因此您可以将它们保留在现有的 Natvis 文件中,只要它使用我们的架构,该文件就可以工作。
不支持该Usage
属性,尽管架构需要 该属性
。但是,LLDB 不限制对 C++ 中定义的运算符的访问,因此任何需要的运算符都可以在 C++ 中定义。
//
您可以使用独立版本的 Android Studio Profiler 来衡量应用的性能。要启动分析器,请执行以下操作:
分析器显示以下类别的实时使用统计信息:CPU、内存、网络和能源。
有关某个类别的更多详细信息,请单击该类别的图表。
有关如何使用分析器的更多信息,请参阅Android Studio Profiler 文档
/
本指南介绍了如何修改 AGDE 项目中的build.gradle
文件,以便您可以在 Android Studio 中打开。本指南主要适用于管理 AGDE 项目的制造工程师。
在完成本指南中的更改后,您应该:
AGDE 以基于实验性的功能 Gradle 插件功能制造而成,支持Ninja 作为 Android 制造系统。
注意:这些更改依赖于 Android Gradle 插件中的实验性功能,功能可能会发生变化或被移除。
更改项目级build.gradle
以引用 Android Gradle 插件版本 7.3.0-alpha02 或更高版本。
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.3.0-alpha02'
}
}
此变更生效后,您仍应能够在 Visual Studio 中编写项目。我们建议您立即试用,因为规定在接下来的更改之前进行调试将很容易。
调用最新版本的Tepot示例具有的脚本run-msbuild.bat
。此脚本调用一个名为,查找和调用MSBuild 的版本。
将run-msbuild.bat
复制到包含应用级build.gradle
文件的文件夹中。
注意:build.gradle
修改该文件后发布的 APK,该文件用于创建 APK。
build.gradle
文件这个步骤的主要目标是配置对run-msbuild.bat
的调用以及移除对MSBUILD_*
的引用。
将更ndkVersion
改为特定的 NDK 版本。例如:
android {
ndkVersion "22.1.7171670"
}
将更minSdkVersion
改为特定的 SDK 版本。例如:
android {
defaultConfig {
minSdkVersion 30
}
}
添加一个部分,以对项目的解决方案调用run-msbuild.bat
。
android {
defaultConfig {
externalNativeBuild {
experimentalProperties["ninja.abiFilters"] = [ "x86", "arm64-v8a" ]
experimentalProperties["ninja.path"] = "Teapot.sln"
experimentalProperties["ninja.configure"] = "run-msbuild"
experimentalProperties["ninja.arguments"] = [
"\${ndk.moduleMakeFile}",
"-p:Configuration=\${ndk.variantName}",
"-p:Platform=Android-\${ndk.abi}",
"-p:NinjaBuildLocation=\${ndk.buildRoot}",
"-p:NinjaProject=GameApplication",
"-p:RequireAndroidNdkVersion=\${ndk.moduleNdkVersion}",
"-p:RequireMinSdkVersion=\${ndk.minPlatform}",
"-t:GenerateBuildNinja"
]
}
}
}
删除所有的MSBUILD_JNI_LIBS_SRC_DIR
、MSBUILD_ANDROID_OUTPUT_APK_NAME
和MSBUILD_ANDROID_GRADLE_BUILD_OUTPUT_DIR
使用代码。
通常,应用级build.gradle
文件中的以下代码块可以完全删除。
sourceSets {
main {
jniLibs.srcDirs = [MSBUILD_JNI_LIBS_SRC_DIR]
}
}
applicationVariants.all { variant ->
variant.outputs.all {
outputFileName = MSBUILD_ANDROID_OUTPUT_APK_NAME
}
}
buildDir = MSBUILD_ANDROID_GRADLE_BUILD_OUTPUT_DIR
此功能是实验功能,因此,如果您能提供反馈,我们将不会提供胜任性。提供方法如下:
///
///