生成过程

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 文件的生成:

签名属性

签名属性控制应用程序包的签名方式,以便将其安装到 Android 设备上。 为了更快地生成迭代,Xamarin.Android 任务不会在生成过程中为包签名,因为签名很慢。 相反,它们在安装之前或导出过程中由 IDE 或安装生成目标进行签名(如有必要)。 调用 SignAndroidPackage 目标将生成一个在输出目录中带有 -Signed.apk 后缀的包。

默认情况下,如果需要,签名目标会生成一个新的调试签名密钥。 如果你希望使用特定的密钥,例如在生成服务器上,则使用以下 MSBuild 属性:

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" />

该文件可轻松适应于其他语言。