Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In .NET gibt es kein Konzept eines Android-Bindungsprojekts als separater Projekttyp. Alle MSBuild-Elementgruppen oder Buildaktionen, die in Xamarin.Android-Bindungsprojekten funktionieren, werden über eine .NET für Android-App oder -Bibliothek unterstützt.
So migrieren Sie eine Xamarin.Android-Bindungsbibliothek zu einer .NET für Android-Klassenbibliothek:
Erstellen Sie in Visual Studio ein neues Java Library Binding-Projekt mit demselben Namen wie Ihr Xamarin.Android-Bindungsprojekt:
Beim Öffnen der Projektdatei wird bestätigt, dass Sie über ein .NET SDK-Formatprojekt verfügen:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net8.0-android</TargetFramework> <SupportedOSPlatformVersion>21</SupportedOSPlatformVersion> <Nullable>enable</Nullable> <ImplicitUsings>enable</ImplicitUsings> </PropertyGroup> </Project>Hinweis
Die Projektdatei für eine Android-Bindungsbibliothek ist identisch mit der Projektdatei für eine Android-Klassenbibliothek.
Fügen Sie Dem Projekt Ihr Java Archive (JAR) oder Android Archive (AAR) hinzu, und stellen Sie sicher, dass die Buildaktion auf AndroidLibrary festgelegt ist.
Kopieren Sie alle Transformationen oder Ergänzungen aus Ihrer Xamarin.Android-Bindungsbibliothek.
Nicht unterstützte veraltete Optionen
Die folgenden Legacyoptionen werden nicht mehr unterstützt. Die unterstützten Alternativen sind seit mehreren Jahren verfügbar, und die reibungsloseste Migrationsoption besteht darin, Ihre aktuellen Projekte mit diesen Optionen zu aktualisieren und zu testen, bevor Sie sie zu .NET migrieren.
AndroidClassParser
jar2xml ist keine gültige Option für die $(AndroidClassParser) Eigenschaft mehr.
class-parse ist jetzt die Standard- und nur unterstützte Option.
class-parse nutzt viele neue moderne Features, die nicht verfügbar sind jar2xml, z. B.:
- Automatische Parameternamen für Klassenmethoden (wenn Ihr Java-Code mit
javac -parameterskompiliert wird). - Kotlin-Unterstützung.
- Support für statische/standardmäßige Schnittstellenmember (DIM).
- Java-Unterstützung für Nullable Reference Type (NRT)-Anmerkungen.
AndroidCodegenTarget
XamarinAndroid ist keine gültige Option für die $(AndroidCodegenTarget) Eigenschaft mehr.
XAJavaInterop1 ist jetzt die Standard- und nur unterstützte Option.
Wenn Sie in Ihren Additions Dateien über handgebundenen Code verfügen, der mit dem generierten Bindungscode interagiert, muss er möglicherweise aktualisiert werden, damit er kompatibel ist XAJavaInterop1.
Standardmäßige Dateieinbindung
Aufgrund der folgenden Dateistruktur:
Transforms/
Metadata.xml
foo.jar
Transforms\*.xmlDateien werden automatisch als @(TransformFile) Element eingeschlossen, und.jar/.aarDateien werden automatisch als @(AndroidLibrary) Element eingeschlossen. Dies bindet C#-Typen für die in foo.jar gefundenen Java-Typen unter Verwendung der Metadatenkorrekturen von Transforms\Metadata.xml.
Das standardmäßige Globbingverhalten für android-bezogene Dateien wird in AutoImport.props definiert. Dieses Verhalten kann für Android-Elemente deaktiviert werden, indem die $(EnableDefaultAndroidItems) Eigenschaft auf falsefestgelegt wird, oder das gesamte Standardverhalten der Elementeinschluss kann durch Festlegen der $(EnableDefaultItems) Eigenschaft auf falsedeaktiviert werden.
Unerwünschte .jar oder .aar Dateien könnten mit den Standard-Wildcards enthalten sein. Beispielsweise ergeben sich die folgenden C#-Compilerfehler aus einer AndroidStudio\gradle\wrapper\gradle-wrapper.jar unbeabsichtigt gebundenen Datei:
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)'
Um dieses Problem zu beheben, können Sie die spezifische Datei in Ihrer Projektdatei entfernen:
<ItemGroup>
<AndroidLibrary Remove="AndroidStudio\gradle\wrapper\gradle-wrapper.jar" />
</ItemGroup>
Alternativ können Sie alle Dateien in einem Ordner ausschließen:
<AndroidLibrary Remove="AndroidStudio\**\*" />
Neue Elementgruppennamen
<AndroidLibrary> ist jetzt die empfohlene Elementgruppe für alle .jar und .aar Dateien. In Xamarin.Android wurden die folgenden Elementgruppen verwendet, die stattdessen Elementmetadaten verwenden können, um dasselbe Ergebnis zu erzielen:
| Legacy-Artikelgruppe | Neue Elementgruppe | Elementmetadaten | Legacy-Projekttyp |
|---|---|---|---|
AndroidAarLibrary |
AndroidLibrary |
Bind="false" |
Anwendung |
AndroidJavaLibrary |
AndroidLibrary |
Bind="false" |
Anwendungs- oder Klassenbibliothek |
EmbeddedJar |
AndroidLibrary |
n/a | Bindungsprojekt |
EmbeddedReferenceJar |
AndroidLibrary |
Bind="false" |
Bindungsprojekt |
InputJar |
AndroidLibrary |
Pack="false" |
Bindungsprojekt |
LibraryProjectZip |
AndroidLibrary |
n/a | Bindungsprojekt |
Betrachten Sie eine .aar- oder .jar-Datei, bei der Sie nicht daran interessiert sind, eine C#-Bindung einzuschließen. Dies ist üblich für Fälle, in denen Sie über Java- oder Kotlin-Abhängigkeiten verfügen, die Sie nicht von C# aufrufen müssen. In diesem Fall können Sie die Bind-Metadaten auf false festlegen. Standardmäßig wird die Datei von den Standard-Wildcards erfasst. Sie können auch das Update Attribut verwenden, um die Bind Metadaten festzulegen:
<ItemGroup>
<AndroidLibrary Update="foo.jar" Bind="false">
</ItemGroup>
In einem Android-Klassenbibliotheksprojekt würde dies die .jar Datei wie folgt innerhalb des resultierenden NuGet-Pakets neu verteilen. In einem Android-Anwendungsprojekt würde dies die .jar Datei in die resultierende .apk datei oder .aab Datei einschließen. Keines würde eine C#-Bindung für diese Java-Bibliothek enthalten.
Eingebettete JAR/AAR-Dateien
In Xamarin.Android wurde der Java-Code .jar oder .aar häufig als eingebettete Ressource in die Bindung .dll eingebettet. Dies führte jedoch zu langsamen Builds, da jeder .dll geöffnet und nach Java-Code gescannt werden muss. Wenn gefunden, muss sie auf den Datenträger extrahiert werden, der verwendet werden soll.
In .NET wird Java Code nicht mehr in die .dll eingebettet. Der App-Buildprozess enthält automatisch alle .jar- oder .aar-Dateien, die er im selben Verzeichnis findet wie einen Verweis auf .dll.
Wenn ein Projekt über <PackageReference> oder <ProjectReference> auf eine Bindung verweist, funktioniert alles einwandfrei, und es sind keine weiteren Überlegungen erforderlich. Wenn jedoch ein Projekt auf eine Bindung mittels <Reference> verweist, muss sich das .jar/.aar neben dem .dll befinden. Dies gilt für die folgende Referenz:
<Reference Include="MyBinding.dll" />
Ein Verzeichnis wie im folgenden Beispiel funktioniert nicht:
lib/
MyBinding.dll
Stattdessen muss das Verzeichnis auch den systemeigenen Code enthalten:
lib/
MyBinding.dll
mybinding.jar
Überlegungen zur Migration
Standardmäßig sind mehrere neue Features festgelegt, um Bindungen zu erzeugen, die ihren Java-Entsprechungen besser entsprechen. Wenn Sie jedoch ein vorhandenes Bindungsprojekt migrieren, können diese Features möglicherweise Bindungen erstellen, die nicht API-kompatibel mit Ihren vorhandenen Bindungen sind. Um die Kompatibilität aufrechtzuerhalten, möchten Sie diese neuen Features möglicherweise deaktivieren oder ändern.
Schnittstellenkonstanten
Traditionell hat C# nicht erlaubt, Konstanten in einem interface zu deklarieren, was ein häufiges Muster in Java ist.
public interface Foo {
public static int BAR = 1;
}
Dieses Muster wurde zuvor durch das Erstellen einer Alternative class unterstützt, die die Konstanten enthält:
public abstract class Foo : Java.Lang.Object
{
public static int Bar = 1;
}
Bei C# 8 werden diese Konstanten auf das interface-Element gesetzt.
public interface IFoo
{
public static int Bar = 1;
}
Dies bedeutet jedoch, dass die alternative Klasse, von der der vorhandene Code abhängig sein kann, nicht mehr generiert wird.
Wenn Sie die $(AndroidBoundInterfacesContainConstants)-Eigenschaft in der Projektdatei auf false festlegen, wird das Legacy-Verhalten wiederhergestellt.
Geschachtelte Schnittstellentypen
Traditionell erlaubt C# es nicht, geschachtelte Typen in einem interface zu deklarieren, was in Java hingegen erlaubt ist.
public interface Foo {
public class Bar { }
}
Dieses Muster wurde durch Verschieben des geschachtelten Typs in einen Typ der obersten Ebene mit einem generierten Namen unterstützt, der aus der Schnittstelle und dem geschachtelten Typnamen besteht:
public interface IFoo { }
public class IFooBar : Java.Lang.Object { }
Mit C# 8 können geschachtelte Typen innerhalb von dem interface platziert werden.
public interface IFoo
{
public class Bar : Java.Lang.Object { }
}
Dies bedeutet jedoch, dass die Klasse der obersten Ebene, von der vorhandener Code abhängig sein kann, nicht mehr generiert wird.
Wenn Sie die $(AndroidBoundInterfacesContainTypes)-Eigenschaft in der Projektdatei auf false festlegen, wird das Legacy-Verhalten wiederhergestellt.
Wenn Sie z. B. einen Hybridansatz verwenden möchten, um vorhandene geschachtelte Typen in einen Typ der obersten Ebene zu verschieben, aber zulassen, dass zukünftige geschachtelte Typen verschachtelt bleiben, können Sie dies auf der interface Ebene metadata angeben, indem Sie das unnest Attribut festlegen. Die Einstellung true bewirkt, dass alle geschachtelten Typen „unverschachtelt“ werden (Legacyverhalten):
<attr path="/api/package[@name='my.package']/interface[@name='Foo']" name="unnest">true</attr>
Die Einstellung false bewirkt, dass geschachtelte Typen in interface geschachtelt bleiben (.NET-Verhalten):
<attr path="/api/package[@name='my.package']/interface[@name='Foo']" name="unnest">false</attr>
Mit diesem Ansatz können Sie die Eigenschaft $(AndroidBoundInterfacesContainTypes) auf true belassen und unnest auf true für jedes interface mit geschachtelten Typen setzen, das Sie derzeit haben. Diese bleiben immer Typen der obersten Ebene, während alle später eingeführten geschachtelten Typen geschachtelt werden.
Statische und Standard-Interface-Mitglieder (DIM)
Traditionell hat C# nicht zugelassen, dass Schnittstellen static Member und default Methoden enthalten:
public interface Foo {
public static void Bar () { ... }
public default void Baz () { ... }
}
Statische Member auf Schnittstellen wurden durch Verschieben in ein gleichgeordnetes Element unterstützt class:
public interface IFoo { }
public class Foo
{
public static void Bar () { ... }
}
default Schnittstellenmethoden sind traditionell nicht gebunden, da sie nicht erforderlich sind und kein C#-Konstrukt vorhanden war, um sie zu unterstützen.
Mit C# 8 werden static- und default-Mitglieder in Schnittstellen unterstützt, ähnlich wie in der Java-Schnittstelle.
public interface IFoo
{
public static void Bar () { ... }
public default void Baz () { ... }
}
Dies bedeutet jedoch, dass das alternative gleichgeordnete Element class mit static-Members nicht mehr generiert wird.
Wenn Sie die $AndroidBoundInterfacesContainStaticAndDefaultInterfaceMethods-Eigenschaft in der Projektdatei auf false festlegen, wird das Legacy-Verhalten wiederhergestellt.
Nullwerte zulassende Verweistypen
Unterstützung für Nullable Reference Types (NRT) wurde in Xamarin.Android 11.0 hinzugefügt. NRT-Unterstützung kann mithilfe des standardmäßigen .NET-Mechanismus aktiviert werden:
<PropertyGroup>
<Nullable>enable</Nullable>
</PropertyGroup>
Da die Standardeinstellung für .NET lautet disable, gilt dies auch für Xamarin.Android-Projekte.
Resource.designer.cs
In Xamarin.Android haben Java-Bindungsprojekte das Generieren einer Resource.designer.cs Datei nicht unterstützt. Da Bindungsprojekte nur Klassenbibliotheken in .NET sind, wird diese Datei generiert. Dies kann bei der Migration vorhandener Projekte zu einer bedeutenden Änderung führen.
Ein Beispiel für einen Fehler bei dieser Änderung ist, wenn ihre Bindung eine Im Stammnamespace benannte Resource Klasse generiert:
error CS0101: The namespace 'MyBinding' already contains a definition for 'Resource'
Oder im Fall von AndroidX gibt es Projektdateien mit - im Namen, zum Beispiel androidx.window/window-extensions.csproj. Dies führt zum Stammnamespace window-extensions und zu ungültigem C#-Code in 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
Um die Generierung Resource.designer.cs zu deaktivieren, legen Sie die Eigenschaft $(AndroidGenerateResourceDesigner) auf false in Ihrer Projektdatei fest.
<PropertyGroup>
<AndroidGenerateResourceDesigner>false</AndroidGenerateResourceDesigner>
</PropertyGroup>