Xamarin.Android 项目迁移

.NET Android 应用的 .NET 8 项目类似于以下示例:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net8.0-android</TargetFramework>
    <OutputType>Exe</OutputType>
  </PropertyGroup>
</Project>

对于库项目,可以完全省略 $(OutputType) 属性或将 Library 指定为属性值。

.NET 配置文件

.NET Android 项目不支持 Foo.dll.configFoo.exe.config配置文件<dllmap> 配置元素在 .NET Core 中根本不受支持,并且 System.Configuration.ConfigurationManager 等兼容性包的其他元素类型在 Android 项目中从不受支持。

对 MSBuild 属性的更改

不应使用 $(AndroidSupportedAbis) 属性:

<PropertyGroup>
  <!-- Used in Xamarin.Android projects -->
  <AndroidSupportedAbis>armeabi-v7a;arm64-v8a;x86;x86_64</AndroidSupportedAbis>
</PropertyGroup>

相反,$(AndroidSupportedAbis) 属性应替换为 .NET 运行时标识符:

<PropertyGroup>
  <!-- Used in .NET Android projects -->
  <RuntimeIdentifiers>android-arm;android-arm64;android-x86;android-x64</RuntimeIdentifiers>
</PropertyGroup>

有关运行时标识符的详细信息,请参阅 .NET RID 目录

下表显示了 .NET Android 中已更改的其他 MSBuild 属性:

属性 注释
$(AndroidUseIntermediateDesignerFile) 默认为 True
$(AndroidBoundExceptionType) 默认为 System。 此属性会更改各种方法引发的异常类型,以更好地与 .NET 语义保持一致,但会牺牲与 Xamarin.Android 的兼容性。 有关详细信息,请参阅一些新包装的 Java 异常使用不同于相关 BCL 类型的 BCL 异常
$(AndroidClassParser) 默认为 class-parsejar2xml 不受支持。
$(AndroidDexTool) 默认为 d8dx 不受支持。
$(AndroidCodegenTarget) 默认为 XAJavaInterop1XamarinAndroid 不受支持。
$(AndroidManifest) 在项目的根中默认为 AndroidManifest.xml,因为 Properties\AssemblyInfo.cs 不再用于 SDK 样式的项目。 如果存在 Properties\AndroidManifest.xml,还将检测并使用它,以简化迁移。
$(DebugType) 默认为 portablefullpdbonly 不受支持。
$(MonoSymbolArchive) False,因为 mono-symbolicate 不受支持。

此外,如果使用 @(InputJar)@(EmbeddedJar)@(LibraryProjectZip) 启用 Java 绑定,则 $(AllowUnsafeBlocks) 属性默认为 True

注意

不支持从 Android 应用引用 Android Wear 项目。

对 AndroidManifest.xml 的更改

在 Xamarin.Android、Java 和 Kotlin Android 项目中,<uses-sdk/> 元素表示应用支持的最低 Android 版本,以及应用编译所面向的目标 Android 版本:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="1"
    android:versionName="1.0"
    package="com.companyname.myapp">
  <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="33" />
  <application android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" />
</manifest>

有关 <uses-sdk/> 元素的详细信息,请参阅 Android 文档

在 .NET 8 Android 应用中,MSBuild 属性用于设置这些值。 使用 MSBuild 属性还有其他好处。 在大多数情况下,应删除 <uses-sdk/> 元素,转而选择项目 .csproj 文件中的值:

<Project>
  <PropertyGroup>
    <TargetFramework>net8.0-android</TargetFramework>
    <SupportedOSPlatformVersion>21</SupportedOSPlatformVersion>
  </PropertyGroup>
</Project>

在此示例中,net8.0-androidnet8.0-android34.0 的简写。 .NET 的后续版本将跟踪 .NET 发布时可用的最新 Android 版本。

TargetFramework 映射到 android:targetSdkVersion。 在生成时,此值将自动包含在 <uses-sdk/> 元素中。 以这种方式使用 TargetFramework 的好处是,可以获得 net8.0-android34.0 的 Android API 34 的匹配 C# 绑定。 Android 的发布独立于 .NET 的发布周期,因此当绑定可用于下一个 Android 版本时,可以灵活地选择 net8.0-android35.0

同样,SupportedOSPlatformVersion 映射到 android:minSdkVersion。 在生成时,此值将自动包含在 <uses-sdk/> 元素中。 Android API 用 SupportedOSPlatformAttribute 来装饰,这样即可得到调用 API 的生成警告,这些 API 仅适用于其中可运行应用的部分 Android 版本:

error CA1416: This call site is reachable on 'Android' 21.0 and later. `ConnectivityManager.ActiveNetwork` is only supported on: 'Android' 23.0 and later.

为安全地使用此 API,可以在项目中声明更高的 SupportedOSPlatformVersion,或在运行时使用 IsAndroidVersionAtLeast API:

if (OperatingSystem.IsAndroidVersionAtLeast(23))
{
    // Use the API here
}

默认文件包含

AutoImport.props 中定义了默认的 .NET Android 相关文件通配行为。 可以通过将 $(EnableDefaultAndroidItems) 设置为 false 来禁用 Android 项的此行为,也可以通过将 $(EnableDefaultItems) 设置为 false 来禁用所有默认项包含行为。 有关详细信息,请参阅工作负载属性文件

运行时行为

在不同平台上,对 .NET 5+ 中的 String.IndexOf() 方法有一些行为更改。 有关详细信息,请参阅 .NET 全球化和 ICU

链接器

.NET 5+ 针对链接器提供了新的设置:

  • <PublishTrimmed>true</PublishTrimmed>
  • <TrimMode>link</TrimMode>,它可启用成员级剪裁。

有关详细信息,请参阅剪裁选项

在 .NET Android 项目中,默认情况下,Debug 生成不使用链接器,而 Release 生成设置 PublishTrimmed=trueTrimMode=linkTrimMode=copyused 是 .NET SDK 的默认值,但不适用于移动应用。 但如果需要,仍可选择 TrimMode=copyused

如果使用旧的 AndroidLinkMode 设置,则 SdkOnlyFull 默认为等效的链接器设置:

  • <PublishTrimmed>true</PublishTrimmed>
  • <TrimMode>link</TrimMode>

对于 AndroidLinkMode=SdkOnly,仅标记为 %(Trimmable) 的 BCL 和 SDK 程序集会在成员级建立链接。 AndroidLinkMode=Full 在所有 .NET 程序集上设置 %(TrimMode)=link

提示

应迁移到新的链接器设置,因为 AndroidLinkMode 设置最终将停用。

预先编译

$(RunAOTCompilation) 是新的 MSBuild 属性,用于启用预先 (AOT) 编译。 此属性也用于 Blazor WASM$(AotAssemblies) 属性还支持 AOT 编译,以帮助从 Xamarin.Android 项目迁移到 .NET Android 项目。

提示

应迁移到新的 $(RunAOTCompilation) 属性,因为 .NET 7 中已停用 $(AotAssemblies)

发布内部版本默认使用以下 AOT 属性值:

<PropertyGroup Condition="'$(Configuration)' == 'Release'">
  <RunAOTCompilation>true</RunAOTCompilation>
  <AndroidEnableProfiledAot>true</AndroidEnableProfiledAot>
</PropertyGroup>

这是 $(RunAOTCompilation)$(AndroidEnableProfiledAot) 属性未设置时的行为,此行为为启动时间和应用大小选择最佳设置。

要禁用 AOT,需显式地将 $(RunAOTCompilation)$(AndroidEnableProfiledAot) 属性设置为 false:

<PropertyGroup Condition="'$(Configuration)' == 'Release'">
  <RunAOTCompilation>false</RunAOTCompilation>
  <AndroidEnableProfiledAot>false</AndroidEnableProfiledAot>
</PropertyGroup>

支持的编码

如果 Xamarin.Android 应用使用某些国际代码集,则必须在项目文件中使用 Mandroidl18n MSBuild 属性对其进行显式指定,确保链接器可以包含支持资源。 有关此生成属性的详细信息,请参阅 MAndroidl18n

然而 Mandroidl18n MSBuild 属性在 .NET Android 应用中不受支持。 但在 System.TextEncoding.CodePages NuGet 包中受支持。 有关详细信息,请参阅 CodePagesEncodingProvider

.NET CLI

.NET Android 支持使用 .NET 命令行接口 (.NET CLI) 来创建、生成、发布和运行 Android 应用。

dotnet new

可以使用 dotnet new 通过按现有 .NET 模板的模式和命名命名的项目模板和项模板创建新的 .NET Android 项目和项:

模板 简称 语言 标记
Android 活动模板 android-activity C# Android
Android Java 库绑定 android-bindinglib C# Android
Android 布局模板 android-layout C# Android
Android 类库 androidlib C# Android
Android 应用程序 android C# Android

以下示例展示了如何使用 dotnet new 来创建各种类型的 .NET Android 项目:

dotnet new android            --output MyAndroidApp     --packageName com.mycompany.myandroidapp
dotnet new androidlib         --output MyAndroidLibrary
dotnet new android-bindinglib --output MyJavaBinding

创建 .NET Android 项目后,可以使用项模板向项目中添加项:

dotnet new android-activity --name LoginActivity --namespace MyAndroidApp
dotnet new android-layout   --name MyLayout      --output Resources/layout

dotnet build & publish

对于 .NET Android,dotnet build 生成可运行的应用。 这意味着在生成过程中创建 .apk.aab 文件,并在 .NET SDK 中对 MSBuild 任务进行重新排序,确保其在生成过程中运行。 因此,.NET Android 在生成过程中进行以下操作:

  • 运行 aapt 以生成 Resource.designer.cs 并且可能针对 @(AndroidResource) 文件中的问题发出生成错误。
  • 编译 C# 代码。
  • 运行 ILLink MSBuild 目标建立链接。
  • 生成 java 存根,以及 AndroidManifest.xml
  • 通过 javac 编译 java 代码。
  • 通过 d8/r8 将 java 代码转换为 .dex
  • 创建 .apk.aab 并对其签名。

保留 dotnet publish,以针对 Google Play 和其他分发机制(如临时)发布应用。 它还使用不同的密钥为 .apk.aab 签名。

注意

IDE 内部的行为会有所不同。 如果 $(BuildingInsideVisualStudio)true,则 Build 目标不会生成 .apk 文件。 IDE 将调用 Install 目标进行部署,这将生成 .apk 文件。 此行为与 Xamarin.Android 匹配。

dotnet run

dotnet run 可用于通过 --project 参数在设备或模拟器上启动应用:

dotnet run --project HelloAndroid.csproj

或者,可以使用 Run MSBuild 目标:

dotnet build HelloAndroid.csproj -t:Run

另请参阅