Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En .NET, no hay ningún concepto de un proyecto de enlace de Android como un tipo de proyecto independiente. Cualquiera de los grupos de elementos de MSBuild o las acciones de compilación que funcionan en los proyectos de vinculación de Xamarin.Android son compatibles con aplicaciones o bibliotecas .NET para Android.
Para migrar una biblioteca de enlaces de Xamarin.Android a una biblioteca de clases de .NET para Android:
En Visual Studio, cree un proyecto de enlace de biblioteca de Java para Android con el mismo nombre que el proyecto de enlace de Xamarin.Android:
Al abrir el archivo del proyecto, se confirmará que tiene un proyecto de estilo SDK de .NET:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net8.0-android</TargetFramework> <SupportedOSPlatformVersion>21</SupportedOSPlatformVersion> <Nullable>enable</Nullable> <ImplicitUsings>enable</ImplicitUsings> </PropertyGroup> </Project>Nota:
El archivo de proyecto de una biblioteca de enlaces de Android es idéntico al archivo de proyecto de una biblioteca de clases de Android.
Agregue el archivo de Java (JAR) o Android Archive (AAR) al proyecto y asegúrese de que su acción de compilación esté establecida en AndroidLibrary.
Copie las transformaciones o adiciones de la biblioteca de enlaces de Xamarin.Android.
Opciones heredadas no admitidas
Ya no se admiten las siguientes opciones heredadas. Las alternativas admitidas están disponibles durante varios años y la opción de migración más fluida es actualizar y probar los proyectos actuales con estas opciones antes de migrarlos a .NET.
AndroidClassParser
jar2xml ya no es una opción válida para la $(AndroidClassParser) propiedad . class-parse ahora es la opción predeterminada y solo admitida.
class-parse aprovecha muchas características modernas nuevas que no están disponibles en jar2xml, como:
- Nombres de parámetro automático para los métodos de clase (si el código Java se compila con
javac -parameters). - Compatibilidad con Kotlin.
- Compatibilidad con miembros de interfaz estáticos/predeterminados (DIM).
- Compatibilidad con anotaciones de tipo de referencia anulable (NRT) en Java.
AndroidCodegenTarget
XamarinAndroid ya no es una opción válida para la $(AndroidCodegenTarget) propiedad . XAJavaInterop1 ahora es la opción predeterminada y solo admitida.
Si tiene código escrito manualmente en los archivos Additions que interactúa con el código de enlace generado, es posible que deba actualizarse para que sea compatible con XAJavaInterop1.
Inclusión de archivos predeterminada
Dada la siguiente estructura de archivos:
Transforms/
Metadata.xml
foo.jar
Transforms\*.xml los archivos se incluyen automáticamente como un @(TransformFile) elemento y .jar/.aar los archivos se incluyen automáticamente como un @(AndroidLibrary) elemento. Esto enlazará los tipos de C# para los tipos de Java que se encuentran en foo.jar mediante las correcciones de metadatos de Transforms\Metadata.xml.
El comportamiento predeterminado de globbing de archivos relacionado con Android se define en AutoImport.props. Este comportamiento se puede deshabilitar para los elementos de Android estableciendo la propiedad $(EnableDefaultAndroidItems) en false, o bien se puede deshabilitar todo el comportamiento de inclusión de elementos predeterminados estableciendo la propiedad $(EnableDefaultItems) en false.
Los archivos .jar o .aar no deseados se pueden incluir con los caracteres comodín predeterminados. Por ejemplo, los siguientes errores del compilador de C# se derivan de un AndroidStudio\gradle\wrapper\gradle-wrapper.jar archivo enlazado involuntariamente:
Org.Gradle.Cli.AbstractCommandLineConverter.cs(11,89): error CS0535: 'Download' does not implement interface member 'IDownload.Download(URI, File)'
Org.Gradle.Wrapper.Download.cs(10,60): error CS0535: 'AbstractCommandLineConverter' does not implement interface member 'ICommandLineConverter.Convert(ParsedCommandLine, Object)'
Para solucionar este problema, puede quitar el archivo específico en el archivo del proyecto:
<ItemGroup>
<AndroidLibrary Remove="AndroidStudio\gradle\wrapper\gradle-wrapper.jar" />
</ItemGroup>
Como alternativa, podría excluir todos los archivos de una carpeta:
<AndroidLibrary Remove="AndroidStudio\**\*" />
Nuevos nombres de grupo de elementos
<AndroidLibrary> es ahora el grupo de elementos recomendado que se usará para todos los .jar archivos y .aar . En Xamarin.Android, se usaron los siguientes grupos de elementos, que en su lugar pueden usar metadatos de elementos para lograr el mismo resultado:
| Grupo de elementos antiguos | Nuevo grupo de elementos | Metadatos de elementos | Tipo de proyecto heredado |
|---|---|---|---|
AndroidAarLibrary |
AndroidLibrary |
Bind="false" |
Aplicación |
AndroidJavaLibrary |
AndroidLibrary |
Bind="false" |
Biblioteca de aplicaciones o clases |
EmbeddedJar |
AndroidLibrary |
N/A | Proyecto vinculante |
EmbeddedReferenceJar |
AndroidLibrary |
Bind="false" |
Proyecto de vinculación |
InputJar |
AndroidLibrary |
Pack="false" |
Proyecto de vinculación |
LibraryProjectZip |
AndroidLibrary |
N/A | Proyecto de vinculación |
Considera un .aar o .jar archivo, en el que no estás interesado en incluir una vinculación de C#. Esto es habitual en los casos en los que tiene dependencias de Java o Kotlin a las que no es necesario llamar desde C#. En este caso, puede configurar los metadatos Bind a false. De forma predeterminada, los caracteres comodín predeterminados recogen el archivo. También puede usar el Update atributo para establecer los Bind metadatos:
<ItemGroup>
<AndroidLibrary Update="foo.jar" Bind="false">
</ItemGroup>
En un proyecto de biblioteca de clases de Android, esto redistribuiría el .jar archivo dentro del paquete NuGet resultante tal cual. En un proyecto de aplicación de Android, esto incluiría el archivo .jar en el archivo resultante .apk o .aab. Tampoco incluiría un enlace de C# para esta biblioteca de Java.
Archivos JAR/AAR incrustados
En Xamarin.Android, Java .jar o .aar a menudo se insertó en la vinculación .dll como recurso incrustado. Sin embargo, esto llevó a compilaciones lentas, ya que cada .dll debe abrirse y examinarse para código Java. Si se encuentra, debe ser extraído al disco para ser utilizado.
En .NET, el código Java ya no está incrustado en .dll. El proceso de compilación de la aplicación incluirá automáticamente cualquier archivo .jar o .aar que encuentre en el mismo directorio que un archivo al que se hace .dll referencia.
Si un proyecto hace referencia a una vinculación a través de <PackageReference> o <ProjectReference>, entonces todo funciona y no se requieren consideraciones adicionales. Sin embargo, si un proyecto hace referencia a un enlace a través del <Reference>, el .jar/.aar debe ubicarse junto al .dll. Es decir, para la siguiente referencia:
<Reference Include="MyBinding.dll" />
Un directorio como el del ejemplo siguiente no funcionará:
lib/
MyBinding.dll
En su lugar, el directorio también debe contener el código nativo:
lib/
MyBinding.dll
mybinding.jar
Consideraciones sobre la migración
Hay varias características nuevas establecidas de forma predeterminada para ayudar a generar enlaces que mejor coincidan con sus homólogos de Java. Pero si vas a migrar un proyecto de enlace existente, estas características pueden crear enlaces que no sean compatibles con la API de los enlaces existentes. Para mantener la compatibilidad, es posible que desee deshabilitar o modificar estas nuevas características.
Constantes de interfaz
Tradicionalmente, C# no ha permitido que las constantes se declaren en , interfaceque es un patrón común en Java:
public interface Foo {
public static int BAR = 1;
}
Este patrón se admitía anteriormente mediante la creación de una alternativa class que contiene las constantes:
public abstract class Foo : Java.Lang.Object
{
public static int Bar = 1;
}
Con C# 8, estas constantes se colocan en :interface
public interface IFoo
{
public static int Bar = 1;
}
Sin embargo, esto significa que la clase alternativa a la que puede depender el código existente ya no se genera.
Al configurar la $(AndroidBoundInterfacesContainConstants) propiedad a false en el archivo del proyecto, se revertirá al comportamiento heredado.
Tipos de interfaz anidados
Tradicionalmente, C# no ha permitido que los tipos anidados se declaren en un interface, lo cual está permitido en Java.
public interface Foo {
public class Bar { }
}
Este patrón se admitía moviendo el tipo anidado a un tipo de nivel superior con un nombre generado compuesto por la interfaz y el nombre del tipo anidado:
public interface IFoo { }
public class IFooBar : Java.Lang.Object { }
Con C# 8, los tipos anidados se pueden definir en interface:
public interface IFoo
{
public class Bar : Java.Lang.Object { }
}
Sin embargo, esto significa que la clase de nivel superior en la que puede depender el código existente ya no se genera.
Al establecer la propiedad $(AndroidBoundInterfacesContainTypes) a false en el archivo del proyecto, se revertirá al comportamiento heredado.
Si desea usar un enfoque híbrido, por ejemplo, para mantener los tipos anidados existentes movidos a un tipo de nivel superior, pero permitir que los tipos anidados futuros permanezcan anidados, puede especificarlo en el interface nivel mediante metadata para establecer el unnest atributo. Si se establece en true, se producirá un "desanidamiento" de los tipos anidados (comportamiento heredado):
<attr path="/api/package[@name='my.package']/interface[@name='Foo']" name="unnest">true</attr>
Si se establece en false, el resultado será que los tipos anidados permanecerán anidados en interface (comportamiento de .NET):
<attr path="/api/package[@name='my.package']/interface[@name='Foo']" name="unnest">false</attr>
Con este enfoque, podrías dejar la propiedad $(AndroidBoundInterfacesContainTypes) como true y establecer unnest en true para cada interface con los tipos anidados que tienes actualmente. Estos siempre seguirán siendo tipos de nivel superior, mientras que los nuevos tipos anidados introducidos más adelante se anidarán.
Miembros de interfaz estáticos y predeterminados (DIM)
Tradicionalmente, C# no permite que las interfaces contengan static miembros y default métodos:
public interface Foo {
public static void Bar () { ... }
public default void Baz () { ... }
}
Se han admitido miembros estáticos en interfaces moviéndolos a una class del mismo nivel:
public interface IFoo { }
public class Foo
{
public static void Bar () { ... }
}
default Los métodos de interfaz no se han enlazado tradicionalmente, ya que no son necesarios y no se ha producido una construcción de C# para admitirlos.
Con C# 8 static y default los miembros se admiten en interfaces, lo que refleja la interfaz de Java:
public interface IFoo
{
public static void Bar () { ... }
public default void Baz () { ... }
}
Sin embargo, esto significa que el hermano alternativo class que contiene miembros static ya no se generará.
Al establecer la propiedad $AndroidBoundInterfacesContainStaticAndDefaultInterfaceMethods en false en el archivo del proyecto, se revertirá al comportamiento heredado.
Tipos de referencia anulables
Se ha agregado compatibilidad con tipos de referencia que aceptan valores NULL (NRT) en Xamarin.Android 11.0. La compatibilidad con NRT se puede habilitar mediante el mecanismo estándar de .NET:
<PropertyGroup>
<Nullable>enable</Nullable>
</PropertyGroup>
Dado que el valor predeterminado para .NET es disable, el mismo se aplica a los proyectos de Xamarin.Android.
Resource.designer.cs
En Xamarin.Android, los proyectos de enlace de Java no admiten la generación de un Resource.designer.cs archivo. Dado que los proyectos de enlace son simplemente bibliotecas de clases en .NET, este archivo se generará. Esto podría ser un cambio importante al migrar proyectos existentes.
Un ejemplo de error de este cambio es si el enlace genera una clase denominada Resource en el espacio de nombres raíz:
error CS0101: The namespace 'MyBinding' already contains a definition for 'Resource'
O bien, en el caso de AndroidX, hay archivos de proyecto con - en el nombre, como androidx.window/window-extensions.csproj. Esto da como resultado el espacio de nombres raíz window-extensions y C# no válido en Resource.designer.cs:
error CS0116: A namespace cannot directly contain members such as fields, methods or statements
error CS1514: { expected
error CS1022: Type or namespace definition, or end-of-file expected
Para deshabilitar la generación Resource.designer.cs, establece la propiedad $(AndroidGenerateResourceDesigner) en false en el archivo del proyecto:
<PropertyGroup>
<AndroidGenerateResourceDesigner>false</AndroidGenerateResourceDesigner>
</PropertyGroup>