Xamarin.Android 项目迁移

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

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

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

.NET 配置文件

.NET for Android 项目中不支持配置文件,例如 Foo.dll.configFoo.exe.config。 .NET Core 完全不支持 <dllmap> 配置元素,Android 项目从未支持过兼容包的其他元素类型,例如:System.Configuration.ConfigurationManager

对 MSBuild 属性的更改

不应使用 $(AndroidSupportedAbis) 属性:

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

而是应当将 $(AndroidSupportedAbis) 属性替换为 .NET 运行时标识符:

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

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

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

properties 评论
$(AndroidUseIntermediateDesignerFile) 默认为 True
$(AndroidBoundExceptionType) 默认为 System。 此属性更改从各种方法引发的异常类型,从而以与 Xamarin.Android 的兼容性为代价更好地与 .NET 语义保持一致。 有关详细信息,请参阅某些新的包装 Java 异常使用与相关 BCL 类型不同的 BCL 异常。
$(AndroidClassParser) 默认为 class-parsejar2xml 不受支持。
$(AndroidDexTool) 默认为 d8dx 不受支持。
$(AndroidCodegenTarget) 默认为 XAJavaInterop1XamarinAndroid 不受支持。
$(AndroidManifest) 在项目的根目录中默认为 AndroidManifest.xml,因为 SDK 样式项目中不再使用 Properties\AssemblyInfo.cs。 如果 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 的好处是,你可以获得适用于 Android API 34 for net8.0-android34.0 的匹配 C# 绑定。 Android 的发布独立于 .NET 发布周期,因此当绑定可用于下一个 Android 版本时,我们可以灵活地选择使用 net8.0-android35.0

同样,SupportedOSPlatformVersion 映射到 android:minSdkVersion。 在生成时,此值将自动包含在 <uses-sdk/> 元素中。 Android API 使用 SupportedOSPlatformAttribute 进行修饰,以便在调用仅适用于应用可以运行的某些 Android 版本的 API 时收到生成警告:

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
}

默认文件包含

默认的 .NET for Android 相关文件通配行为在 AutoImport.props 中定义。 设置 $(EnableDefaultAndroidItems)false 禁用 Android 项执行此行为,或设置 $(EnableDefaultItems)false 禁用所有默认项包含行为。 有关详细信息,请参阅工作负荷 props 文件

运行时行为

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

链接器

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

  • <PublishTrimmed>true</PublishTrimmed>
  • <TrimMode>partial</TrimMode>,用于剪裁已启用剪裁的程序集。

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

默认情况下,在 .NET for Android 项目中,Debug 生成不使用链接器,而 Release 生成会设置 PublishTrimmed=trueTrimMode=partial

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

  • <PublishTrimmed>true</PublishTrimmed>
  • <TrimMode>partial</TrimMode>

使用 AndroidLinkMode=SdkOnly 时,只有标有 %(Trimmable) 的 BCL 和 SDK 程序集才会在成员级别上链接。 AndroidLinkMode=Full 在所有 .NET 程序集上设置 %(TrimMode)=partial

提示

应该迁移到新链接器设置,因为最终会弃用 AndroidLinkMode 设置。

预先编译

$(RunAOTCompilation) 是 MSBuild 新属性,用于启用预先 (AoT) 编译。 这与 Blazor WASM 使用的属性相同。 $(AotAssemblies) 属性还支持 AOT,以帮助从 Xamarin.Android 项目迁移到 .NET for Android 项目。 但是,此属性在 .NET 7 中已弃用。

版本生成默认使用下列 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

但是, .NET for Android 应用中不支持 Mandroidl18n MSBuild 属性。 相反,System.TextEncoding.CodePages NuGet 包提供支持。 有关详细信息,请参阅 CodePagesEncodingProvider

.NET CLI

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

dotnet new

dotnet new 可用于使用项目模板和项模板创建新的 .NET for Android 项目和项,这些模板的命名遵循现有 .NET 模板的模式和命名:

模板 简称 语言 标记
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 for Android 项目:

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

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

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

dotnet build 和 dotnet publish

对于 .NET for Android,dotnet build 生成可运行的应用。 这意味着在生成过程中创建 .apk.aab 文件,并对 .NET SDK 中的 MSBuild 任务重新排序,以便它们在生成期间运行。 因此,.NET for 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

另请参阅