Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Ett .NET för Android Java-bindningsbibliotek försöker automatisera mycket av det arbete som krävs för att binda ett befintligt Android-bibliotek med hjälp av ett verktyg som ibland kallas bindningsgeneratorn. När du binder ett Java-bibliotek inspekterar .NET för Android Java-klasserna och genererar en lista över alla paket, typer och medlemmar som ska bindas. Den här listan över API:er lagras i en XML-fil som finns i {project directory}\obj{Configuration}\api.xml.
Bindningsgeneratorn kommer att använda api.xml som en riktlinje för att generera de nödvändiga C#-omslutningsklasserna. Följande kodfragment är ett exempel på innehållet i 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>
I det här exemplet deklarerar api.xml en klass i paketet android med namnet Manifest som utökar java.lang.Object.
I många fall krävs mänsklig hjälp för att få Java-API:et att kännas mer ".NET like" eller för att åtgärda problem som hindrar bindningssammansättningen från att kompileras. Det kan till exempel vara nödvändigt att ändra Java-paketnamn till .NET-namnområden, byta namn på en klass eller ändra returtypen för en metod.
Dessa ändringar bör inte uppnås genom att ändra api.xml direkt. I stället registreras ändringar i särskilda XML-filer som tillhandahålls av java-bindningsbiblioteksmallen. När du kompilerar .NET för Android-bindningssammansättningen påverkas bindningsgeneratorn av dessa mappningsfiler när bindningssammansättningen skapas
Den Metadata.xml filen är den viktigaste av dessa filer eftersom den tillåter allmänna ändringar i bindningen, till exempel:
Byta namn på namnrymder, klasser, metoder eller fält så att de följer .NET-konventioner.
Ta bort namnrymder, klasser, metoder eller fält som inte behövs.
Flytta klasser till olika namnområden.
Om du lägger till ytterligare stödklasser för att göra så att bindningens utformning följer .NET-ramverksmönster.
Metadata.xml transformationsfil
Som vi redan har lärt oss används filen Metadata.xml av bindningsgeneratorn för att påverka skapandet av bindningssammansättningen. Metadataformatet använder XPath-syntax .
Den här implementeringen är nästan en fullständig implementering av XPath 1.0 och stöder därför objekt i 1.0-standarden. Den här filen är en kraftfull XPath-baserad mekanism för att ändra, lägga till, dölja eller flytta element eller attribut i API-filen. Alla regelelement i metadataspecifikationen innehåller ett path attribut för att identifiera de noder som regeln ska tillämpas på. Följande är de tillgängliga elementtyperna:
- add-node – Lägger till en underordnad nod i den nod som anges av sökvägsattributet.
- attr – Anger värdet för ett attribut för elementet som anges av sökvägsattributet.
- remove-node – Tar bort noder som matchar en angiven XPath.
Följande är ett exempel på en Metadata.xml fil:
<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>
Följande visar några av de vanligare XPath-elementen för Java-API:et:
interface– Används för att hitta ett Java-gränssnitt. t.ex./interface[@name='AuthListener'].class– Används för att hitta en klass . t.ex./class[@name='MapView'].method– Används för att hitta en metod i en Java-klass eller ett Java-gränssnitt. t.ex./class[@name='MapView']/method[@name='setTitleSource'].parameter– Identifiera en parameter för en metod. t.ex./parameter[@name='p0']
Lägga till typer
Elementet add-node instruerar .NET for Android-bindningsprojektet att lägga till en ny klass iapi.xml. Följande kodfragment dirigerar till exempel bindningsgeneratorn för att skapa en klass med en konstruktor och ett enda fält:
<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>
Ta bort typer
Det är möjligt att instruera .NET for Android Bindings Generator att ignorera en Java-typ och inte binda den. Detta görs genom att lägga till ett remove-node XML-element i Metadata.xml-filen :
<remove-node path="/api/package[@name='{package_name}']/class[@name='{name}']" />
Byta namn på medlemmar
Det går inte att byta namn på medlemmar genom att redigera api.xml filen direkt eftersom .NET för Android kräver att de ursprungliga JNI-namnen (Java Native Interface) kommunicerar med Java. Därför kan attributet //class/@name inte ändras; om det görs, fungerar inte bindningen.
Tänk på det fall där vi vill byta namn på en typ, android.Manifest.
För att åstadkomma detta kan vi försöka redigera api.xml direkt och byta namn på klassen så här:
<attr path="/api/package[@name='android']/class[@name='Manifest']"
name="name">NewName</attr>
Detta resulterar i att bindningsgeneratorn skapar följande C#-kod för omslutningsklassen:
[Register ("android/NewName")]
public class NewName : Java.Lang.Object { ... }
Observera att omslutningsklassen har bytt namn till NewName, medan den ursprungliga Java-typen fortfarande Manifestär . Det är inte längre möjligt för bindningsklassen .NET för Android att komma åt några metoder på android.Manifest. Omslutningsklassen är bunden till en obefintlig Java-typ.
Om du vill ändra det "hanterade" namnet på en omsluten typ (eller metod) måste du ange attributet som visas i detta exempel:
<attr path="/api/package[@name='android']/class[@name='Manifest']"
name="managedName">NewName</attr>
Användning managedName krävs när du försöker byta namn på en medlem, till exempel klasser, gränssnitt, metoder och parametrar.
Byta namn på omslutande klasser EventArg
När .NET för Android-bindningsgeneratorn identifierar en onXXX setter-metod för en lyssnartyp genereras en C#-händelse och EventArgs underklass för att stödja ett .NET-smaksatt API för det Java-baserade lyssnarmönstret. Tänk till exempel på följande Java-klass och -metod:
com.someapp.android.mpa.guidance.NavigationManager.on2DSignNextManuever(NextManueverListener listener);
.NET för Android släpper prefixet on från setter-metoden och använder 2DSignNextManuever i stället som grund för underklassens EventArgs namn. Underklassen får namnet något som liknar:
NavigationManager.2DSignNextManueverEventArgs
Det här är inte ett juridiskt C#-klassnamn. För att åtgärda problemet måste bindningsförfattaren argsType använda attributet och ange ett giltigt C#-namn för underklassen EventArgs :
<attr path="/api/package[@name='com.someapp.android.mpa.guidance']/
interface[@name='NavigationManager.Listener']/
method[@name='on2DSignNextManeuver']"
name="argsType">NavigationManager.TwoDSignNextManueverEventArgs</attr>
Attribut som stöds
I följande avsnitt beskrivs några av attributen för att transformera Java-API:er.
argsType
Det här attributet placeras på settermetoder för att namnge den EventArg underklass som ska genereras för att stödja Java-lyssnare. Detta beskrivs mer detaljerat i avsnittet Byt namn på EventArg Wrapper-klasser i den här guiden.
evenemangsnamn
Anger ett namn på en händelse. Om namnet är tomt förhindrar det händelsegenerering. Detta beskrivs mer detaljerat i avsnittet Byt namn på EventArg Wrapper-klasser.
managedName
Detta används för att ändra namnet på ett paket, en klass, en metod eller en parameter. Om du till exempel vill ändra namnet på Java-klassen MyClass till NewClassName:
<attr path="/api/package[@name='com.my.application']/class[@name='MyClass']"
name="managedName">NewClassName</attr>
I nästa exempel visas ett XPath-uttryck för att byta namn på metoden java.lang.object.toString till Java.Lang.Object.NewManagedName:
<attr path="/api/package[@name='java.lang']/class[@name='Object']/method[@name='toString']"
name="managedName">NewMethodName</attr>
managedType
managedType används för att ändra returtypen för en metod. I vissa situationer härleder bindningsgeneratorn felaktigt returtypen för en Java-metod, vilket resulterar i ett kompileringstidsfel. En möjlig lösning i den här situationen är att ändra metodens returtyp.
Till exempel anser bindningsgeneratorn att Java-metoden de.neom.neoreadersdk.resolution.compareTo() bör returnera en int och ta Object som parametrar, vilket resulterar i felmeddelandet Fel CS0535: 'DE. Neom.Neoreadersdk.Resolution implementerar inte gränssnittsmedlemmen "Java.Lang.IComparable.CompareTo(Java.Lang.Object)".
Följande kodfragment visar hur du ändrar den första parameterns typ av den genererade C#-metoden från en DE.Neom.Neoreadersdk.Resolution till en Java.Lang.Object:
<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>
managedReturn
Ändrar returtypen för en metod. Detta ändrar inte returattributet (eftersom ändringar för att returnera attribut kan resultera i inkompatibla ändringar i JNI-signaturen). I följande exempel ändras metodens append returtyp från SpannableStringBuilder till IAppendable:
<attr path="/api/package[@name='android.text']/
class[@name='SpannableStringBuilder']/
method[@name='append']"
name="managedReturn">Java.Lang.IAppendable</attr>
Förvrängd
Verktyg som fördunklar Java-bibliotek kan störa .NET för Android-bindningsgeneratorn och dess förmåga att generera C#-omslutningsklasser. Egenskaper för fördunklade klasser är:
- Klassnamnet innehåller en $, d.v.s. a$.class
- Klassnamnet är helt komprometterat med gemener, d.v.s. a.class
Det här kodfragmentet är ett exempel på hur du genererar en icke-fördunklad C#-typ:
<attr path="/api/package[@name='{package_name}']/class[@name='{name}']"
name="obfuscated">false</attr>
propertyName
Det här attributet kan användas för att ändra namnet på en hanterad egenskap.
Ett specialiserat fall av användning propertyName omfattar en situation där en Java-klass bara har en setter-metod för ett fält. I det här fallet skulle bindningsgeneratorn vilja skapa en skrivskyddad egenskap, något som inte rekommenderas i .NET. Följande kodfragment visar hur du "tar bort" .NET-egenskaperna genom att ange propertyName till en tom sträng:
<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>
Observera att metoderna setter och getter fortfarande skapas av bindningsgeneratorn. De konverteras helt enkelt inte till en .NET-egenskap.
avsändare
Anger vilken parameter för en metod som ska vara parametern sender när metoden mappas till en händelse. Värdet kan vara true eller false. Som exempel:
<attr path="/api/package[@name='android.app']/
interface[@name='TimePickerDialog.OnTimeSetListener']/
method[@name='onTimeSet']/
parameter[@name='view']"
name="sender">true</ attr>
synlighet
Det här attributet används för att ändra synligheten för en klass, metod eller egenskap. Det kan till exempel vara nödvändigt att höja upp en protected Java-metod så att motsvarande C#-omslutning är public:
<!-- 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>