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.
Eine .NET für Android Java Binding Library versucht, einen Großteil der Arbeit zu automatisieren, die zum Binden einer vorhandenen Android-Bibliothek mit Hilfe eines Tools erforderlich ist, das manchmal als Bindings-Generator bezeichnet wird. Beim Binden einer Java-Bibliothek prüft .NET für Android die Java-Klassen und generiert eine Liste aller Pakete, Typen und Member, die gebunden werden sollen. Diese Liste der APIs wird in einer XML-Datei gespeichert, die unter {project directory}\obj{Configuration}\api.xml zu finden ist.
Der Bindungsgenerator verwendet die api.xml-Datei als Richtlinie zum Generieren der erforderlichen C# Wrapperklassen. Der folgende Codeausschnitt ist ein Beispiel für den Inhalt von api.xml:
<api>
<package name="android">
<class abstract="false" deprecated="not deprecated" extends="java.lang.Object"
extends-generic-aware="java.lang.Object"
final="true"
name="Manifest"
static="false"
visibility="public">
<constructor deprecated="not deprecated" final="false"
name="Manifest" static="false" type="android.Manifest"
visibility="public">
</constructor>
</class>
...
</api>
In diesem Beispiel deklariert api.xml eine Klasse im android Paket namens Manifest, die java.lang.Object erweitert.
In vielen Fällen ist menschliche Unterstützung erforderlich, damit die Java-API .NET-ähnlicher aussieht oder Probleme korrigiert, die eine Kompilierung der Bindungsassembly verhindern. Es kann beispielsweise erforderlich sein, Java-Paketnamen in .NET-Namespaces zu ändern, eine Klasse umzubenennen oder den Rückgabetyp einer Methode zu ändern.
Diese Änderungen sollten nicht erreicht werden, indem api.xml direkt geändert werden. Stattdessen werden Änderungen in speziellen XML-Dateien aufgezeichnet, die von der Java-Bindungsbibliotheksvorlage bereitgestellt werden. Beim Kompilieren der .NET für Android-Binding-Assembly wird der Bindings Generator beim Erstellen der Binding-Assembly durch diese Zuordnungsdateien beeinflusst.
Die Metadata.xml Datei ist die wichtigste dieser Dateien, da sie allgemeine Änderungen an der Bindung zulässt, z. B.:
Umbenennen von Namespaces, Klassen, Methoden oder Feldern, sodass sie den .NET-Konventionen entsprechen.
Entfernen von Namespaces, Klassen, Methoden oder Feldern, die nicht benötigt werden.
Verschieben von Klassen in andere Namespaces.
Hinzufügen weiterer Unterstützungsklassen, damit der Entwurf der Bindung die .NET Framework-Muster befolgt.
Metadata.xml Transformationsdatei
Wie bereits erwähnt, wird die Datei Metadata.xml vom Bindungsgenerator verwendet, um die Erstellung der Bindungsassembly zu beeinflussen. Das Metadatenformat verwendet XPath-Syntax .
Diese Implementierung ist fast eine komplette Implementierung von XPath 1.0, sodass Elemente im 1.0-Standard unterstützt werden. Diese Datei ist ein leistungsfähiger XPath-basierter Mechanismus zum Ändern, Hinzufügen, Ausblenden oder Verschieben von Elementen oder Attributen in der API-Datei. Alle Regelelemente in der Metadatenspezifikation enthalten ein path Attribut, um die Knoten zu identifizieren, auf die die Regel angewendet werden soll. Nachfolgend sind die verfügbaren Elementtypen aufgeführt:
- add-node – Fügt einen untergeordneten Knoten an den durch das Path-Attribut angegebenen Knoten an.
- attr – Legt den Wert eines Attributs des durch das Path-Attribut angegebenen Elements fest.
- remove-node – Entfernt Knoten, die einem angegebenen XPath entsprechen.
Nachfolgend finden Sie ein Beispiel für eine Metadata.xml-Datei:
<metadata>
<!-- Normalize the namespace for .NET -->
<attr path="/api/package[@name='com.evernote.android.job']"
name="managedName">Evernote.AndroidJob</attr>
<!-- Don't need these packages for the .NET for Android binding/public API -->
<remove-node path="/api/package[@name='com.evernote.android.job.v14']" />
<remove-node path="/api/package[@name='com.evernote.android.job.v21']" />
<!-- Change a parameter name from the generic p0 to a more meaningful one. -->
<attr path="/api/package[@name='com.evernote.android.job']/class[@name='JobManager']/method[@name='forceApi']/parameter[@name='p0']"
name="name">api</attr>
</metadata>
Nachstehend sind einige der gängigsten XPath-Elemente für die Java-APIs aufgeführt:
interface– Wird verwendet, um eine Java-Schnittstelle zu finden. Beispiel:/interface[@name='AuthListener'].class– Wird verwendet, um eine Klasse zu finden. Beispiel:/class[@name='MapView'].method– Wird verwendet, um eine Methode für eine Java-Klasse oder -Schnittstelle zu finden. Beispiel:/class[@name='MapView']/method[@name='setTitleSource'].parameter– Identifizieren eines Parameters für eine Methode. Beispiel:/parameter[@name='p0']
Hinzufügen von Typen
Das add-node Element teilt dem .NET für Android-Bindungsprojekt mit, api.xml eine neue Klasse hinzuzufügen. Der folgende Codeausschnitt weist den Bindungsgenerator beispielsweise an, eine Klasse mit einem Konstruktor und einem einzelnen Feld zu erstellen:
<add-node path="/api/package[@name='org.alljoyn.bus']">
<class abstract="false" deprecated="not deprecated" final="false" name="AuthListener.AuthRequest" static="true" visibility="public" extends="java.lang.Object">
<constructor deprecated="not deprecated" final="false" name="AuthListener.AuthRequest" static="false" type="org.alljoyn.bus.AuthListener.AuthRequest" visibility="public" />
<field name="p0" type="org.alljoyn.bus.AuthListener.Credentials" />
</class>
</add-node>
Entfernen von Typen
Es ist möglich, den .NET für Android Bindings Generator anzuweisen, einen Java-Typ zu ignorieren und nicht zu binden. Dazu fügen Sie ein remove-node XML-Element zur Datei Metadata.xml hinzu:
<remove-node path="/api/package[@name='{package_name}']/class[@name='{name}']" />
Umbenennen von Mitgliedern
Das Umbenennen von Mitgliedern kann nicht erfolgen, indem sie die api.xml Datei direkt bearbeiten, da .NET für Android die ursprünglichen JNI-Namen (Java Native Interface) erfordert, um mit Java zu sprechen. Daher kann das //class/@name-Attribut nicht geändert werden. Andernfalls funktioniert die Bindung nicht.
Stellen Sie sich vor, dass der Typ android.Manifest umbenannt werden soll.
Um dies zu erreichen, könnten Sie versuchen, die api.xml direkt zu bearbeiten und die Klasse wie folgt umzubenennen:
<attr path="/api/package[@name='android']/class[@name='Manifest']"
name="name">NewName</attr>
Dies führt dazu, dass der Bindungsgenerator den folgenden C# Code für die Wrapperklasse erstellt:
[Register ("android/NewName")]
public class NewName : Java.Lang.Object { ... }
Beachten Sie, dass die Wrapperklasse in NewName umbenannt wurde, während der ursprüngliche Java-Typ weiterhin Manifest ist. Es ist nicht mehr möglich, dass die .NET für Android-Bindungsklasse auf methoden android.Manifestzugreifen kann; die Wrapperklasse ist an einen nicht vorhandenen Java-Typ gebunden.
Um den "verwalteten" Namen eines umbrochenen Typs (oder Methode) ordnungsgemäß zu ändern, muss das managedName Attribut wie in diesem Beispiel dargestellt festgelegt werden:
<attr path="/api/package[@name='android']/class[@name='Manifest']"
name="managedName">NewName</attr>
Die Verwendung managedName ist erforderlich, wenn Sie versuchen, elemente wie Klassen, Schnittstellen, Methoden und Parameter umzubenennen.
Umbenennen von EventArg Wrapperklassen
Wenn der .NET-für-Android-Bindungsgenerator eine onXXX Settermethode für einen Listener-Typ identifiziert, werden ein C#-Ereignis sowie eine EventArgs Unterklasse generiert, um eine an .NET angelehnte API für das Java-basierte Listener-Muster zu unterstützen. Betrachten Sie als Beispiel die folgende Java-Klasse und -Methode:
com.someapp.android.mpa.guidance.NavigationManager.on2DSignNextManuever(NextManueverListener listener);
.NET für Android wird das Präfix on bei der Settermethode weglassen und stattdessen 2DSignNextManuever als Grundlage für den Namen der EventArgs-Unterklasse nutzen. Der Name der Unterklasse lautet in etwa wie folgt:
NavigationManager.2DSignNextManueverEventArgs
Dies ist kein gültiger C#-Klassenname. Um dieses Problem zu beheben, muss der Bindungsersteller das argsType-Attribut verwenden und einen gültigen C#-Namen für die EventArgs-Unterklasse angeben:
<attr path="/api/package[@name='com.someapp.android.mpa.guidance']/
interface[@name='NavigationManager.Listener']/
method[@name='on2DSignNextManeuver']"
name="argsType">NavigationManager.TwoDSignNextManueverEventArgs</attr>
Unterstützte Attribute
In den folgenden Abschnitten werden einige Attribute zum Transformieren von Java-APIs beschrieben.
Argumenttyp
Dieses Attribut wird in Settermethoden eingefügt, um die EventArg-Unterklasse zu benennen, die zur Unterstützung von Java-Listenern generiert wird. Dies wird im Abschnitt Renaming EventArg Wrapper Classes in diesem Handbuch ausführlicher beschrieben.
eventName
Gibt einen Namen für ein Ereignis an. Wenn der Name leer ist, wird die Ereignisgenerierung verhindert. Dies wird im Abschnitt „EventArg-Wrapper-Klassen“ ausführlicher beschrieben.
managedName
Dieses Attribut wird verwendet, um den Namen eines Pakets, einer Klasse, einer Methode oder eines Parameters zu ändern, z. B. zum Ändern des Namens der Java-Klasse MyClass in NewClassName:
<attr path="/api/package[@name='com.my.application']/class[@name='MyClass']"
name="managedName">NewClassName</attr>
Das nächste Beispiel veranschaulicht einen XPath-Ausdruck zum Umbenennen der Methode java.lang.object.toString in Java.Lang.Object.NewManagedName:
<attr path="/api/package[@name='java.lang']/class[@name='Object']/method[@name='toString']"
name="managedName">NewMethodName</attr>
verwalteterTyp
managedType wird verwendet, um den Rückgabetyp einer Methode zu ändern. In einigen Situationen leitet der Bindungsgenerator nicht den richtigen Rückgabetyp einer Java-Methode ab, sodass es beim Kompilieren zu einem Fehler kommt. Eine mögliche Lösung in dieser Situation besteht darin, den Rückgabetyp der Methode zu ändern.
Beispielsweise ist der Bindings-Generator der Ansicht, dass die Java-Methode de.neom.neoreadersdk.resolution.compareTo() eine int als Parameter zurückgeben und als Parameter übernehmen Object soll, was zu der Fehlermeldung "Error CS0535" führt: 'DE. Neom.Neoreadersdk.Resolution" implementiert kein Schnittstellenmitglied "Java.Lang.IComparable.CompareTo(Java.Lang.Object)".
Der folgende Codeausschnitt veranschaulicht, wie der Typ des ersten Parameters der generierten C#-Methode von DE.Neom.Neoreadersdk.Resolution in Java.Lang.Objectgeändert wird:
<attr path="/api/package[@name='de.neom.neoreadersdk']/
class[@name='Resolution']/
method[@name='compareTo' and count(parameter)=1 and
parameter[1][@type='de.neom.neoreadersdk.Resolution']]/
parameter[1]" name="managedType">Java.Lang.Object</attr>
verwaltete Rückgabe
Ändert den Rückgabetyp einer Methode. Dadurch wird das Rückgabeattribut nicht geändert (da Änderungen an Rückgabeattributen zu inkompatiblen Änderungen der JNI-Signatur führen können). Im folgenden Beispiel wird der Rückgabetyp der append-Methode von SpannableStringBuilder zu IAppendable geändert:
<attr path="/api/package[@name='android.text']/
class[@name='SpannableStringBuilder']/
method[@name='append']"
name="managedReturn">Java.Lang.IAppendable</attr>
verschleiert
Tools, die Java-Bibliotheken verschleiern, beeinträchtigen möglicherweise den .NET für Android-Bindungsgenerator und seine Fähigkeit zum Generieren von C#-Wrapperklassen. Zu den Merkmalen von verschleierten Klassen gehören:
- Der Klassenname enthält ein $, z. B. a$.class.
- Der Klassenname besteht ausschließlich aus Kleinbuchstaben, z. B. a.class.
Dieser Codeausschnitt ist ein Beispiel für die Generierung eines „nicht verschleierten“ C#-Typs:
<attr path="/api/package[@name='{package_name}']/class[@name='{name}']"
name="obfuscated">false</attr>
propertyName
Dieses Attribut kann verwendet werden, um den Namen einer verwalteten Eigenschaft zu ändern.
Ein spezieller Fall der Nutzung von propertyName liegt vor, wenn eine Java-Klasse nur über eine Settermethode für ein Feld verfügt. In diesem Fall möchte der Bindungsgenerator eine schreibgeschützte Eigenschaft erstellen, wovon in .NET abgeraten wird. Der folgende Codeausschnitt zeigt, wie die .NET-Eigenschaften „entfernt“ werden, indem propertyName auf eine leere Zeichenfolge festgelegt wird:
<attr path="/api/package[@name='org.java_websocket.handshake']/class[@name='HandshakeImpl1Client']/method[@name='setResourceDescriptor'
and count(parameter)=1
and parameter[1][@type='java.lang.String']]"
name="propertyName"></attr>
<attr path="/api/package[@name='org.java_websocket.handshake']/class[@name='HandshakeImpl1Client']/method[@name='getResourceDescriptor'
and count(parameter)=0]"
name="propertyName"></attr>
Beachten Sie, dass die Setter- und Getter-Methoden weiterhin vom Bindungsgenerator erstellt werden, sie werden nur nicht in eine .NET-Eigenschaft konvertiert.
Absender
Gibt an, welcher Parameter einer Methode der sender-Parameter sein soll, wenn die Methode einem Ereignis zugeordnet wird. Der Wert kann true oder false lauten. Zum Beispiel:
<attr path="/api/package[@name='android.app']/
interface[@name='TimePickerDialog.OnTimeSetListener']/
method[@name='onTimeSet']/
parameter[@name='view']"
name="sender">true</ attr>
Sichtbarkeit
Dieses Attribut wird verwendet, um die Sichtbarkeit einer Klasse, Methode oder Eigenschaft zu ändern. Beispielsweise kann es erforderlich sein, eine protected-Java-Methode höher zu stufen, damit der zugehörige C#-Wrapper public lautet:
<!-- Change the visibility of a class -->
<attr path="/api/package[@name='namespace']/class[@name='ClassName']" name="visibility">public</attr>
<!-- Change the visibility of a method -->
<attr path="/api/package[@name='namespace']/class[@name='ClassName']/method[@name='MethodName']" name="visibility">public</attr>