.NET for Android 的生成过程负责将所有元素结合在一起:生成Resource.designer.cs、支持@(AndroidAsset)@(AndroidResource)以及其他生成操作、生成 Android 可调用包装器,并生成.apk以便在 Android 设备上执行。
应用程序包
从广义上讲,有两种类型的 Android 应用程序包(.apk 文件),.NET for Android 生成系统可以生成:
发行版本,完全是自包含的,不需要额外的包来执行。 这些是提供给应用商店的包。
调试版本则不是这样。
这些包类型与生成包的 MSBuild Configuration 匹配。
快速部署
快速部署的工作方式是进一步缩小 Android 应用程序包大小。 这是通过以下方式完成的:从包中排除应用的程序集,改为将应用的程序集直接部署到应用程序的内部 files 目录(通常位于 /data/data/com.some.package 中)。 内部 files 目录不是全局可写文件夹,因此 run-as 工具用于执行所有命令以将文件复制到该目录中。
此进程加快了生成/部署/调试周期,因为如果只更改了程序集,则不会重新安装该包。 只有更新的程序集才会重新同步到目标设备。
警告
已知快速部署会在阻止 run-as 的设备上失败,这通常包括操作系统早于 Android 5.0 的设备。
这两种格式 .apk 和 .aab 包格式都支持快速部署。
默认情况下,它处于启用状态,并且可以通过将 $(EmbedAssembliesIntoApk) 属性设置为 True 在调试版本中禁用。
请注意,使用 .aab 进行快速部署的速度将比使用 .apk 更慢,因为 .aab 文件必须通过 bundletool 进行处理才能打包和安装。
增强的快速部署模式可与此功能结合使用,进一步提高部署速度。
这会将程序集、本机库、类型映射和 dex 都部署到 files 目录。 但是,只有在更改本机库、绑定或 Java 代码时,才真正需要启用此功能。
MSBuild 项目
.NET for Android 生成过程基于 MSBuild,这也是 Visual Studio for Mac 和 Visual Studio 使用的项目文件格式。 通常,用户不需要手工编辑 MSBuild 文件 - IDE 将创建功能齐全的项目并使用所做的全部更改进行更新,然后根据需要自动调用生成目标。
高级用户可能希望执行 IDE 的 GUI 不支持的操作,因此,可通过直接编辑项目文件来自定义生成过程。 此页面仅记录适用于 Android 的 .NET 功能和自定义项 -- 使用常规 MSBuild 项、属性和目标可以执行更多操作。
绑定项目
以下 MSBuild 属性与绑定项目一起使用:
Resource.designer.cs 生成
以下 MSBuild 属性用于控制 Resource.designer.cs 文件的生成:
$(AndroidAapt2CompileExtraArgs)$(AndroidAapt2LinkExtraArgs)$(AndroidExplicitCrunch)$(AndroidR8IgnoreWarnings)$(AndroidResgenExtraArgs)$(AndroidResgenFile)$(AndroidUseAapt2)$(MonoAndroidResourcePrefix)
签名属性
签名属性控制应用程序包的签名方式,以便将其安装到 Android 设备上。 为了允许更快的生成迭代,.NET for Android 任务不会在生成过程中对包进行签名,因为签名速度相当慢。 相反,它们在安装之前或导出过程中由 IDE 或安装生成目标进行签名(如有必要)。 调用 SignAndroidPackage 目标将生成一个在输出目录中带有 -Signed.apk 后缀的包。
默认情况下,如果需要,签名目标会生成一个新的调试签名密钥。 如果你希望使用特定的密钥,例如在生成服务器上,则使用以下 MSBuild 属性:
$(AndroidDebugKeyAlgorithm)$(AndroidDebugKeyValidity)$(AndroidDebugStoreType)$(AndroidKeyStore)$(AndroidSigningKeyAlias)$(AndroidSigningKeyPass)$(AndroidSigningKeyStore)$(AndroidSigningStorePass)$(JarsignerTimestampAuthorityCertificateAlias)$(JarsignerTimestampAuthorityUrl)
keytool 选项映射
请考虑以下 keytool 调用:
$ keytool -genkey -v -keystore filename.keystore -alias keystore.alias -keyalg RSA -keysize 2048 -validity 10000
Enter keystore password: keystore.filename password
Re-enter new password: keystore.filename password
...
Is CN=... correct?
[no]: yes
Generating 2,048 bit RSA key pair and self-signed certificate (SHA1withRSA) with a validity of 10,000 days
for: ...
Enter key password for keystore.alias
(RETURN if same as keystore password): keystore.alias password
[Storing filename.keystore]
要使用上面生成的密钥存储,请使用属性组:
<PropertyGroup>
<AndroidKeyStore>True</AndroidKeyStore>
<AndroidSigningKeyStore>filename.keystore</AndroidSigningKeyStore>
<AndroidSigningStorePass>keystore.filename password</AndroidSigningStorePass>
<AndroidSigningKeyAlias>keystore.alias</AndroidSigningKeyAlias>
<AndroidSigningKeyPass>keystore.alias password</AndroidSigningKeyPass>
</PropertyGroup>
生成扩展点
.NET for Android 构建系统为想要集成到我们构建过程的用户公开了一些公共扩展点。 为了使用其中一个扩展点,你需要将你的自定义目标添加到 PropertyGroup 中的相应 MSBuild 属性。 例如:
<PropertyGroup>
<AfterGenerateAndroidManifest>
$(AfterGenerateAndroidManifest);
YourTarget;
</AfterGenerateAndroidManifest>
</PropertyGroup>
扩展点包括:
- `$(AfterGenerateAndroidManifest)
- '$(AndroidPrepareForBuildDependsOn)
- `$(BeforeGenerateAndroidManifest)
$(BeforeBuildAndroidAssetPacks)
有关扩展生成过程的警告:如果未正确编写,生成扩展可能会影响生成性能,尤其是在每次生成上运行时。 强烈建议先阅读 MSBuild 文档,再实现此类扩展。
目标定义
在生成过程中,$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets定义了特定于 Android 的 .NET 部分,但构建程序集仍需正常的特定于语言的目标,例如 Microsoft.CSharp.targets。
导入任何语言目标之前,必须设置以下生成属性:
<PropertyGroup>
<TargetFrameworkIdentifier>MonoDroid</TargetFrameworkIdentifier>
<MonoDroidVersion>v1.0</MonoDroidVersion>
<TargetFrameworkVersion>v2.2</TargetFrameworkVersion>
</PropertyGroup>
通过导入 Xamarin.Android.CSharp.targets,可在 C# 中包含所有这些目标和属性:
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
该文件可轻松适应于其他语言。