Java-kötések metaadatai

Az Androidhoz készült .NET Java kötéstár megkísérli automatizálni a meglévő Android könyvtár kötéséhez szükséges munka nagy részét egy olyan eszköz segítségével, amelyet néha Kötésgenerátornak neveznek. Java-kódtár kötésekor az Androidhoz készült .NET megvizsgálja a Java-osztályokat, és létrehoz egy listát az összes kötendő csomagról, típusról és tagról. Az API-k listája egy XML-fájlban van tárolva, amely a(z) {project directory}\obj{Configuration}\api.xml.

A api.xml fájl helye az obj/Hibakeresés mappában

A Bindings Generator a api.xml fájlt fogja használni a szükséges C# burkolóosztályok létrehozásához. Az alábbi kódrészlet a api.xmltartalmára mutat példát:

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

Ebben a példában api.xml deklarál egy osztályt a android csomagban Manifest , amely kiterjeszti a java.lang.Object.

Sok esetben emberi segítségre van szükség ahhoz, hogy a Java API ".NET-hez hasonlóbbnak" érezze magát, vagy hogy kijavítsa azokat a problémákat, amelyek megakadályozzák a kötésszerelvény összeállítását. Szükség lehet például a Java-csomagnevek .NET-névterekre való módosítására, osztály átnevezésére vagy egy metódus visszatérési típusának módosítására.

Ezeket a módosításokat nem szabad közvetlenül a api.xml módosításával elérni. Ehelyett a módosítások speciális XML-fájlokban vannak rögzítve, amelyeket a Java-kötéstár-sablon biztosít. Az Androidhoz készült .NET kötésszerelvény összeállításakor a kötési szerelvény létrehozásakor ezek a leképezési fájlok befolyásolják a kötésgenerátort

A Metadata.xml fájl a legfontosabb ezek közül a fájlok közül, mivel lehetővé teszi a kötés általános célú módosítását, például:

  • Névterek, osztályok, metódusok vagy mezők átnevezése a .NET-konvenciók követéséhez.

  • Távolítsa el a szükségtelen névtereket, osztályokat, metódusokat vagy mezőket.

  • Osztályok áthelyezése különböző névterekre.

  • További támogatási osztályok hozzáadásával a kötés tervezése a .NET-keretrendszer mintáit követi.

Metadata.xml átalakító fájl

Amint azt már megtanultuk, a kötési szerelvény létrehozásának befolyásolására a Kötések generátora használja a Metadata.xml fájlt. A metaadat-formátum XPath-szintaxist használ.

Ez az implementáció az XPath 1.0 szinte teljes implementációja, így támogatja az 1.0 szabvány elemeit. Ez a fájl egy hatékony XPath-alapú mechanizmus az API-fájl bármely elemének vagy attribútumának módosítására, hozzáadására, elrejtésére vagy áthelyezésére. A metaadat-specifikáció összes szabályeleme tartalmaz egy path attribútumot, amely azonosítja azokat a csomópontokat, amelyekre a szabályt alkalmazni kell. Az elérhető elemtípusok a következők:

  • add-node – Hozzáfűz egy gyermekcsomópontot az elérési út attribútum által megadott csomóponthoz.
  • attr – Az útvonalattribútum által megadott elem egyik attribútumának értékét állítja be.
  • remove-node – Eltávolítja a megadott XPath-nak megfelelő csomópontokat.

Az alábbi példa egy Metadata.xml fájlra:

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

Az alábbi lista a Java API-khoz leggyakrabban használt XPath-elemeket sorolja fel:

  • interface – Java-felület megkeresésére szolgál. például /interface[@name='AuthListener'].

  • class – Osztály megkeresésére szolgál. például /class[@name='MapView'].

  • method – Egy Java-osztályon vagy -felületen található metódus megkeresésére szolgál. például /class[@name='MapView']/method[@name='setTitleSource'].

  • parameter – Egy metódus paraméterének azonosítása. például: /parameter[@name='p0']

Típusok hozzáadása

Az add-node elem azt fogja mondani az Android .NET kötési projektjének, hogy adjon hozzá egy új osztályt api.xml. A következő kódrészlet például arra utasítja a Kötésgenerátort, hogy hozzon létre egy konstruktort és egyetlen mezőt tartalmazó osztályt:

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

Típusok eltávolítása

A .NET for Android Bindings Generator utasítható arra, hogy hagyja figyelmen kívül a Java-típust, és ne kösse meg. Ehhez xml-elemet kell hozzáadnia remove-node a Metadata.xml fájlhoz:

<remove-node path="/api/package[@name='{package_name}']/class[@name='{name}']" />

Tagok átnevezése

A tagok átnevezése nem végezhető el közvetlenül a api.xml fájl szerkesztésével, mert az Android .NET-hez az eredeti Java Natív felület (JNI) nevek szükségesek a Java-hoz való beszélgetéshez. Ezért az //class/@name attribútum nem módosítható; ha igen, a kötés nem fog működni.

Fontolja meg azt az esetet, amikor át szeretnénk nevezni egy típust. android.Manifest Ennek érdekében megpróbálhatjuk közvetlenül szerkeszteni api.xml és átnevezni az osztályt a következőképpen:

<attr path="/api/package[@name='android']/class[@name='Manifest']" 
    name="name">NewName</attr>

Ez azt eredményezi, hogy a Bindings Generator a következő C# kódot hozza létre a burkolóosztályhoz:

[Register ("android/NewName")]
public class NewName : Java.Lang.Object { ... }

Figyelje meg, hogy a burkolóosztály átnevezve NewNamelett, míg az eredeti Java-típus még mindig Manifest. Az Androidhoz készült .NET kötésosztály már nem fér hozzá a metódusokhoz android.Manifest; a burkolóosztály nem létező Java-típushoz van kötve.

A burkolt típus (vagy metódus) "felügyelt" nevének megfelelő módosításához be kell állítani az attribútumot az managedName alábbi példában látható módon:

<attr path="/api/package[@name='android']/class[@name='Manifest']" 
    name="managedName">NewName</attr>

A managedName használata szükséges, amikor bármely tag, például osztályok, interfészek, metódusok és paraméterek átnevezésével próbálkozunk.

Burkolóosztályok átnevezése EventArg

Amikor az Androidhoz készült .NET kötésgenerátor azonosít egy onXXXfigyelőtípushoz tartozó setter metódust, a rendszer létrehoz egy C# eseményt és EventArgs alosztályt, amely támogatja a Java-alapú figyelőminta .NET-ízesített API-ját. Vegyük például a következő Java-osztályt és -metódust:

com.someapp.android.mpa.guidance.NavigationManager.on2DSignNextManuever(NextManueverListener listener);

Az Androidhoz készült .NET el fogja hagyni a setter metódus előtagját on, és ehelyett 2DSignNextManuever fog szolgálni az EventArgs alosztály nevének alapjául. Az alosztály neve a következőhöz hasonló lesz:

NavigationManager.2DSignNextManueverEventArgs

Ez nem jogi C#-osztálynév. A probléma megoldásához a kötés szerzőjének az argsType attribútumot kell használnia, és meg kell adnia egy érvényes C#-nevet az EventArgs alosztályhoz:

<attr path="/api/package[@name='com.someapp.android.mpa.guidance']/
    interface[@name='NavigationManager.Listener']/
    method[@name='on2DSignNextManeuver']" 
    name="argsType">NavigationManager.TwoDSignNextManueverEventArgs</attr>

Támogatott attribútumok

Az alábbi szakaszok a Java API-k átalakításának néhány attribútumát ismertetik.

argsType

Ez az attribútum a setter metódusokra kerül, hogy nevezze el a EventArg Java-figyelők támogatásához létrehozandó alosztályt. Ezt részletesebben az útmutató EventArg burkolóosztályok átnevezése című szakaszában ismertetjük.

eseményNeve

Egy esemény nevét adja meg. Ha a név üres, megakadályozza az eseménygenerálást. Az EventArg Burkolóosztályok átnevezése című szakasz részletesebben ismerteti ezt.

kezeltNév

Ez egy csomag, osztály, metódus vagy paraméter nevének módosítására szolgál. Ha például a Java-osztály MyClass nevét a következőre NewClassNameszeretné módosítani:

<attr path="/api/package[@name='com.my.application']/class[@name='MyClass']" 
    name="managedName">NewClassName</attr>

A következő példa egy XPath-kifejezést mutat be a metódus java.lang.object.toString átnevezéséhez a következőre Java.Lang.Object.NewManagedName:

<attr path="/api/package[@name='java.lang']/class[@name='Object']/method[@name='toString']" 
    name="managedName">NewMethodName</attr>

managedType

managedType metódus visszatérési típusának módosítására szolgál. Bizonyos helyzetekben a Bindings Generator helytelenül következteti egy Java-metódus visszatérési típusát, ami fordítási hibát eredményez. Ebben a helyzetben az egyik lehetséges megoldás a metódus visszatérési típusának módosítása.

A Kötések Generátora például úgy véli, hogy a Java metódusnak vissza kell adnia egy int típusú objektumot, és bemeneti paraméterként Object típusú értéket kell fogadnia, ami a CS0535 hibaüzenetet eredményezi: "DE. A Neom.Neoreadersdk.Resolution nem implementálja a "Java.Lang.IComparable.CompareTo(Java.Lang.Object)" felülettagot. Az alábbi kódrészlet bemutatja, hogyan módosíthatja a létrehozott C# metódus első paraméterének típusát a DE.Neom.Neoreadersdk.Resolution-ról egy Java.Lang.Object-re.

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

kezeltVisszatérés

Módosítja a metódus visszatérési típusát. Ez nem módosítja a visszatérési attribútumot (mivel a visszatérési attribútumok módosítása inkompatibilis változásokat eredményezhet a JNI-aláírásban). Az alábbi példában a metódus visszatérési append típusa a következőre SpannableStringBuilderIAppendablemódosul:

<attr path="/api/package[@name='android.text']/
    class[@name='SpannableStringBuilder']/
    method[@name='append']" 
    name="managedReturn">Java.Lang.IAppendable</attr>

Eltorzítva

Azok az eszközök, amelyek elhomályosítják a Java-könyvtárakat, zavarhatják a .NET for Android Binding Generator működését és a C# burkolóosztályok generálását. Az elhomályosított osztályok jellemzői a következők:

  • Az osztálynév tartalmaz egy $, azaz a$.class
  • Az osztály neve teljesen kisbetűkből áll, ami azt jelenti, hogy a.class

Ez a kódrészlet egy példa arra, hogyan hozhat létre C# típust, amely "nem obfuszkált".

<attr path="/api/package[@name='{package_name}']/class[@name='{name}']" 
    name="obfuscated">false</attr>

propertyName

Ez az attribútum egy felügyelt tulajdonság nevének módosítására használható.

A propertyName speciális alkalmazása azt a helyzetet foglalja magában, amikor egy Java-osztálynak csak egy mezőhöz tartozó setter metódusa van. Ebben az esetben a Kötésgenerátor egy írásvédett tulajdonságot szeretne létrehozni, ami a .NET-ben nem ajánlott. Az alábbi kódrészlet bemutatja, hogyan "távolíthatja el" a .NET-tulajdonságokat egy propertyName üres sztringre állítással:

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

Vegye figyelembe, hogy a beállító és a getter metódust továbbra is a Kötések generátora hozza létre, csak nem lesznek .NET-tulajdonsággá konvertálva.

feladó

Meghatározza, hogy a metódus melyik paramétere legyen a sender paraméter, amikor a metódus egy eseményhez van leképezve. Az érték lehet true vagy false. Például:

<attr path="/api/package[@name='android.app']/
    interface[@name='TimePickerDialog.OnTimeSetListener']/
    method[@name='onTimeSet']/
    parameter[@name='view']" 
    name="sender">true</ attr>

láthatóság

Ez az attribútum egy osztály, metódus vagy tulajdonság láthatóságának módosítására szolgál. Előfordulhat például, hogy ki kell emelni egy Java-metódust protected, hogy létrejöjjön a megfelelő C# burkoló 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>