生成过程
Xamarin.Android 生成过程负责将所有内容集合在一起:生成 Resource.designer.cs
,支持 @(AndroidAsset)
、@(AndroidResource)
和其他生成操作,生成 Android 可调用的包装器,以及生成 .apk
以在 Android 设备上执行。
应用程序包
在广义上说,Xamarin.Android 生成系统可以生成两种类型的 Android 应用程序包(.apk
文件):
发行版本,完全是自包含的,不需要额外的包来执行。 这些是提供给应用商店的包。
调试版本则不是。
这些包类型与生成包的 MSBuild Configuration
匹配。
共享运行时
在 Xamarin.Android 11.2 之前,“共享运行时”是一对额外的 Android 包,它们提供基类库(mscorlib.dll
等)和 Android 绑定库(Mono.Android.dll
等)。 调试版本依赖共享运行时替代在 Android 应用程序包中包含基类库和绑定程序集,从而使调试程序包更小。
可以在调试版本中禁用共享运行时,具体方法是将 $(AndroidUseSharedRuntime)
属性设置为 False
。
Xamarin 11.2 中删除了对共享运行时的支持。
快速部署
快速部署的工作方式是进一步缩小 Android 应用程序包大小。 这是通过以下方式完成的:从包中排除应用的程序集,改为将应用的程序集直接部署到应用程序的内部 files
目录(通常位于 /data/data/com.some.package
中)。 内部 files
目录不是全局可写文件夹,因此 run-as
工具用于执行所有命令以将文件复制到该目录中。
此进程加快了生成/部署/调试周期,因为如果只更改了程序集,则不会重新安装该包。 只有更新的程序集才会重新同步到目标设备。
警告
快速部署在阻止 run-as
的设备(通常包括早于 Android 5.0 的设备)上会失败。
快速部署在默认情况下处于启用状态,可以通过将 $(EmbedAssembliesIntoApk)
属性设置为 True
在调试版本中禁用。
增强的快速部署模式可与此功能结合使用,进一步提高部署速度。
这会将程序集、本机库、类型映射和 dex 都部署到 files
目录。 但是,只有在更改本机库、绑定或 Java 代码时,才真正需要启用此功能。
MSBuild 项目
Xamarin.Android 生成过程基于 MSBuild,它也是 Visual Studio for Mac 和 Visual Studio 使用的项目文件格式。 通常,用户不需要手工编辑 MSBuild 文件 - IDE 将创建功能齐全的项目并使用所做的全部更改进行更新,然后根据需要自动调用生成目标。
高级用户可能希望执行 IDE 的 GUI 不支持的操作,因此,可通过直接编辑项目文件来自定义生成过程。 本页仅记录 Xamarin.Android 特定的功能和自定义项 - 可以使用正常的 MSBuild 项、属性和目标执行更多的操作。
绑定项目
以下 MSBuild 属性与绑定项目一起使用:
Resource.designer.cs
生成
以下 MSBuild 属性用于控制 Resource.designer.cs
文件的生成:
$(AndroidAapt2CompileExtraArgs)
$(AndroidAapt2LinkExtraArgs)
$(AndroidExplicitCrunch)
$(AndroidR8IgnoreWarnings)
$(AndroidResgenExtraArgs)
$(AndroidResgenFile)
$(AndroidUseAapt2)
$(MonoAndroidResourcePrefix)
签名属性
签名属性控制应用程序包的签名方式,以便将其安装到 Android 设备上。 为了更快地生成迭代,Xamarin.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>
生成扩展点
Xamarin.Android 为希望连接到我们的生成过程的用户公开一些公共扩展点。 为了使用其中一个扩展点,你需要将你的自定义目标添加到 PropertyGroup
中的相应 MSBuild 属性。 例如:
<PropertyGroup>
<AfterGenerateAndroidManifest>
$(AfterGenerateAndroidManifest);
YourTarget;
</AfterGenerateAndroidManifest>
</PropertyGroup>
扩展点包括:
有关扩展生成过程的警告:如果未正确编写,生成扩展可能会影响生成性能,尤其是在每次生成上运行时。 强烈建议先阅读 MSBuild 文档,再实现此类扩展。
目标定义
生成过程的 Xamarin.Android 特定部分在 $(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets
中定义,但生成该程序集时也需要使用正常的语言特定目标,如 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" />
该文件可轻松适应于其他语言。