Migración de proyectos de Xamarin.Android

Un proyecto de .NET 8 para una aplicación de .NET para Android es similar al ejemplo siguiente:

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

Para un proyecto de biblioteca, omite la propiedad $(OutputType) por completo o especifica Library como valor de propiedad.

Archivos de configuración de .NET

No hay compatibilidad con archivos de configuración como Foo.dll.config o Foo.exe.config en .NET para proyectos Android. Los elementos de configuración <dllmap> no se admiten en .NET Core en absoluto y otros tipos de elementos para paquetes de compatibilidad como System.Configuration.ConfigurationManager nunca se han admitido en proyectos de Android.

Cambios en las propiedades de MSBuild

No se debe usar la propiedad $(AndroidSupportedAbis):

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

En su lugar, la propiedad $(AndroidSupportedAbis) debe reemplazarse por identificadores de tiempo de ejecución de .NET:

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

Para obtener más información sobre los identificadores en tiempo de ejecución (RID), consulta el Catálogo de identificadores de entorno de ejecución (RID) de .NET.

La siguiente tabla muestra otras propiedades de MSBuild que han tenido cambios en .NET para Android:

Propiedad Comentarios
$(AndroidUseIntermediateDesignerFile) True es el valor predeterminado.
$(AndroidBoundExceptionType) System es el valor predeterminado. Esta propiedad modifica los tipos de excepciones producidas desde varios métodos para alinearse mejor con la semántica de .NET, a costa de la compatibilidad con Xamarin.Android. Para obtener más información, consulta Algunas de las nuevas excepciones ajustadas de Java usan excepciones de BCL que difieren de los tipos de BCL relacionados.
$(AndroidClassParser) class-parse es el valor predeterminado. jar2xml no se admite.
$(AndroidDexTool) d8 es el valor predeterminado. dx no se admite.
$(AndroidCodegenTarget) XAJavaInterop1 es el valor predeterminado. XamarinAndroid no se admite.
$(AndroidManifest) El valor predeterminado es AndroidManifest.xml en la raíz de los proyectos porque Properties\AssemblyInfo.cs ya no se usa en proyectos de estilo SDK. Properties\AndroidManifest.xml también se detectará y se usará si existe para facilitar la migración.
$(DebugType) portable es el valor predeterminado. No se admitefull ni pdbonly .
$(MonoSymbolArchive) False, ya que mono-symbolicate no se admite.

Además, si el enlace de Java está habilitado con @(InputJar), @(EmbeddedJar) o @(LibraryProjectZip), la propiedad $(AllowUnsafeBlocks) tiene True como valor predeterminado.

Nota:

No se admite la referencia a un proyecto de Android Wear desde una aplicación Android.

Cambios en AndroidManifest.xml

En los proyectos de Android de Xamarin.Android, Java y Kotlin, el elemento <uses-sdk/> denota la versión mínima de Android que admite la aplicación, así como la versión de Android de destino en la que se compila la aplicación:

<?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>

Para obtener más información sobre el elemento <uses-sdk/>, consulta la documentación de Android.

En las aplicaciones de Android de .NET 8, hay propiedades de MSBuild para establecer estos valores. El uso de las propiedades de MSBuild tiene otras ventajas. En la mayoría de los casos, el elemento <uses-sdk/> debe quitarse en favor de los valores del archivo del proyecto .csproj:

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

En este ejemplo, net8.0-android es una abreviatura de net8.0-android34.0. Las versiones futuras de .NET realizarán un seguimiento de la versión más reciente de Android disponible en el momento de la versión de .NET.

TargetFramework se asigna a android:targetSdkVersion. En tiempo de compilación, este valor se incluirá automáticamente en el elemento <uses-sdk/>. La ventaja de usar TargetFramework de esta manera es que se te asigna el enlace de C# coincidente para la API de Android 34 para net8.0-android34.0. Android se libera independientemente del ciclo de versión de .NET, por lo que tenemos la flexibilidad de optar por net8.0-android35.0 cuando hay un enlace disponible para la próxima versión de Android.

Del mismo modo, SupportedOSPlatformVersion se asigna a android:minSdkVersion. En tiempo de compilación, este valor se incluirá automáticamente en el elemento <uses-sdk/>. Las API de Android están decoradas con SupportedOSPlatformAttribute para que recibas advertencias de compilación para llamar a las API que solo están disponibles para algunas de las versiones de Android en las que se puede ejecutar tu aplicación:

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

Para usar esta API de forma segura, puedes declarar un SupportedOSPlatformVersion superior en tu proyecto o usar la API IsAndroidVersionAtLeast en tiempo de ejecución:

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

Inclusión de archivos predeterminada

El comportamiento predeterminado de globbing de archivos relacionados con .NET para Android está definido en AutoImport.props. Este comportamiento se puede deshabilitar para los elementos de Android estableciendo $(EnableDefaultAndroidItems) en false o todo el comportamiento de inclusión de elementos predeterminados se puede deshabilitar estableciendo $(EnableDefaultItems) en false. Para obtener más información, consulta Archivos de propiedades de la carga de trabajo.

Comportamiento en tiempo de ejecución

Hay cambios de comportamiento en e método String.IndexOf() en .NET 5+ en distintas plataformas. Para obtener más información, consulte Globalización de .NET e ICU.

Enlazador

.NET 8 tiene nuevas configuraciones para el enlazador:

  • <PublishTrimmed>true</PublishTrimmed>
  • <TrimMode>partial</TrimMode>, que recorta los ensamblados que han optado por el recorte.

Para obtener más información, consulte opciones de limitación.

De manera predeterminada, en los proyectos .NET para Android, Debug compila sin usar el enlazador, y Release establece PublishTrimmed=true y TrimMode=partial.

Si se usa la configuración AndroidLinkMode, heredado tanto Full como SdkOnly adoptan el valor predeterminado de la configuración del enlazador equivalente:

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

Con AndroidLinkMode=SdkOnly, solo los ensamblados BCL y SDK marcados con %(Trimmable) están vinculados en el nivel de miembro. AndroidLinkMode=Full establece %(TrimMode)=partial en todos los ensamblados de .NET.

Sugerencia

Debes migrar a la nueva configuración del enlazador, ya que la configuración de AndroidLinkMode quedará en desuso.

.NET 9 tiene una nueva configuración para el enlazador:

  • <TrimMode>Full</TrimMode>, que realiza el recorte completo.

Para obtener más información, consulte opciones de limitación.

De manera predeterminada, en los proyectos .NET para Android, Debug compila sin usar el enlazador, y Release establece PublishTrimmed=true y TrimMode=partial.

Compilación Ahead-of-Time

$(RunAOTCompilation) es la nueva propiedad de MSBuild para habilitar la compilación Ahead-Of-Time (AoT). Es la misma propiedad que se usa para Blazor WASM. La propiedad $(AotAssemblies) también habilita AOT, con el fin de ayudar en la migración de proyectos Xamarin.Android a proyectos .NET para Android. Sin embargo, esta propiedad estaba en desuso en .NET 7.

La versión compila de forma predeterminada los siguientes valores de propiedad AOT:

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

Es el comportamiento cuando las propiedades $(RunAOTCompilation) y $(AndroidEnableProfiledAot) están desactivadas y elige la configuración óptima para el tiempo de inicio y el tamaño de la aplicación.

Para deshabilitar AOT, debes establecer explícitamente las propiedades $(RunAOTCompilation) y $(AndroidEnableProfiledAot) en false:

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

Codificaciones compatibles

Si la aplicación Xamarin.Android usa determinados conjuntos de códigos internacionales, deben especificarse explícitamente en el archivo de proyecto mediante la propiedad Mandroidl18n de MSBuild para que el enlazador pueda incluir recursos compatibles. Para obtener más información sobre esta propiedad de compilación, consulta MAndroidl18n.

Sin embargo, la propiedad Mandroidl18n MSBuild no es compatible en aplicaciones .NET para Android. En su lugar, el paquete System.TextEncoding.CodePages de NuGet ofrece compatibilidad. Para obtener más información, consulte CodePagesEncodingProvider.

.NET CLI

.NET para Android es compatible usando la interfaz de línea de comandos de .NET (.NET CLI) para crear, compilar, publicar y ejecutar aplicaciones para Android.

dotnet new

dotnet new se puede usar para crear nuevos proyectos y elementos .NET para Android usando plantillas de proyectos y plantillas de elementos que se nombran siguiendo los patrones y la nomenclatura de las plantillas .NET existentes:

Plantilla Nombre corto Lenguaje Etiquetas
Plantilla de actividad de Android android-activity C# Android
Enlace de la biblioteca de Java para Android android-bindinglib C# Android
Plantilla de diseño de Android android-layout C# Android
Biblioteca de clases de Android androidlib C# Android
Aplicaciones de Android android C# Android

Los siguientes ejemplos muestran cómo usar dotnet new para crear diferentes tipos de proyectos .NET para Android:

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

Una vez creados los proyectos .NET para Android, se pueden usar las plantillas de elementos para agregar elementos a los proyectos:

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

Compilación y publicación de .NET

Para .NET para Android, dotnet build genera una aplicación ejecutable. Esto significa crear un archivo .apk o .aab durante el proceso de compilación y reordenar las tareas de MSBuild desde el SDK de .NET para que se ejecuten durante la compilación. Por lo tanto, .NET para Android realiza lo siguiente durante una compilación:

  • Ejecuta aapt para generar Resource.designer.cs y emitir posibles errores de compilación para problemas en archivos @(AndroidResource).
  • Compilación de código de C#.
  • Ejecuta el destino ILLink de MSBuild para el enlazado.
  • Genere códigos auxiliares de Java y AndroidManifest.xml.
  • Compila código java a través de javac.
  • Convierte el código java a .dex a través de d8/r8.
  • Crea un .apk o .aab y fírmalo.

dotnet publish está reservado para publicar una aplicación para Google Play y otros mecanismos de distribución, como ad hoc. También firma .apk o .aab con claves diferentes.

Nota:

El comportamiento dentro de los IDE variará. El destino Build no generará un archivo .apk si $(BuildingInsideVisualStudio) es true. Los IDE llamarán al destino Install para la implementación, que generará el archivo .apk. Este comportamiento coincide con Xamarin.Android.

dotnet run

dotnet run se puede usar para iniciar aplicaciones en un dispositivo o emulador mediante el argumento --project:

dotnet run --project HelloAndroid.csproj

Como alternativa, puedes usar el destino Run de MSBuild:

dotnet build HelloAndroid.csproj -t:Run

Consulta también