Java bağlama meta verileri

Android için .NET Java Bağlama Kitaplığı , bağlama oluşturucu olarak da bilinen bir aracın yardımıyla mevcut bir Android kitaplığını bağlamak için gereken işlerin çoğunu otomatikleştirmeye çalışır. Bir Java kitaplığını bağlarken, Android için .NET Java sınıflarını inceler ve bağlanacak tüm paketlerin, türlerin ve üyelerin listesini oluşturur. Bu API listesi , {project directory}\obj{Configuration}\api.xmlkonumunda bulunabilen bir XML dosyasında depolanır.

obj/Debug klasöründeki api.xml dosyasının konumu

Bağlama Oluşturucu gerekli C# sarmalayıcı sınıflarını oluşturmak için bir kılavuz olarak api.xml dosyasını kullanır. Aşağıdaki kod parçacığı, api.xmliçeriğinin bir örneğidir:

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

Bu örnekte ,api.xml adlı pakette androidManifest öğesini genişleten java.lang.Objectbir sınıf bildirir.

Çoğu durumda Java API'sinin daha ".NET gibi" hissetmesini sağlamak veya bağlama derlemesinin derlenmesini engelleyen sorunları düzeltmek için insan yardımı gerekir. Örneğin, Java paket adlarını .NET ad alanları olarak değiştirmek, sınıfı yeniden adlandırmak veya bir yöntemin dönüş türünü değiştirmek gerekebilir.

Bu değişiklikler, doğrudanapi.xml değiştirilerek gerçekleştirilmemelidir. Bunun yerine, değişiklikler Java Bağlama Kitaplığı şablonu tarafından sağlanan özel XML dosyalarına kaydedilir. .NET için Android bağlama derlemesi derlenirken, Bağlama Oluşturucu bağlama derlemesi oluştururken bu eşleme dosyalarından etkilenecektir.

bağlamada genel amaçlı değişikliklere izin verdiğinden ,Metadata.xml dosyası bu dosyalardan en önemlisidir:

  • Ad alanlarını, sınıfları, yöntemleri veya alanları yeniden adlandırarak .NET kurallarını izlemelerini sağlar.

  • Gerekli olmayan ad alanlarını, sınıfları, yöntemleri veya alanları kaldırma.

  • Sınıfları farklı ad alanlarına taşıma.

  • .NET framework desenlerine uygun olması için bağlamanın tasarımına ek destek sınıfları eklemek.

Metadata.xml dönüştürme dosyası

Daha önce öğrendiğimiz gibi dosya Metadata.xml Bağlama Oluşturucu tarafından bağlama derlemesinin oluşturulmasını etkilemek için kullanılır. Meta veri biçimi XPath söz dizimini kullanır.

Bu uygulama, XPath 1.0'ın neredeyse eksiksiz bir uygulamasıdır ve bu nedenle 1.0 standardında öğeleri destekler. Bu dosya, API dosyasındaki herhangi bir öğeyi veya özniteliği değiştirmek, eklemek, gizlemek veya taşımak için güçlü bir XPath tabanlı mekanizmadır. Meta veri belirtimindeki tüm kural öğeleri, kuralın uygulanacağı düğümleri tanımlamak için bir path öznitelik içerir. Kullanılabilir öğe türleri şunlardır:

  • add-node : Path özniteliği tarafından belirtilen düğüme bir alt düğüm ekler.
  • attr : path özniteliği tarafından belirtilen öğenin özniteliğinin değerini ayarlar.
  • remove-node – Belirtilen XPath ile eşleşen düğümleri kaldırır.

Aşağıda bir Metadata.xml dosyası örneği verilmiştir:

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

Aşağıda Java API'leri için daha yaygın olarak kullanılan XPath öğelerinden bazıları listelenmiştir:

  • interface – Java arabirimini bulmak için kullanılır. örneğin /interface[@name='AuthListener'].

  • class – Sınıfını bulmak için kullanılır. örneğin /class[@name='MapView'].

  • method – Java sınıfı veya arabiriminde bir yöntemi bulmak için kullanılır. örneğin /class[@name='MapView']/method[@name='setTitleSource'].

  • parameter – Bir yöntemin parametresini tanımlayın. örn. /parameter[@name='p0']

Tür ekleme

öğesi Android add-node için .NET bağlama projesine api.xmlyeni bir sınıf eklemesini söyler. Örneğin, aşağıdaki kod parçacığı Bağlama Oluşturucu'ya oluşturucu ve tek bir alan içeren bir sınıf oluşturmaya yönlendirir:

<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ürler kaldırma

.NET için Android Bağlama Oluşturucu'ya bir Java türünü yok sayması ve bağlamaması talimatı vermek mümkündür. Bu işlem, remove-node dosyasına bir XML öğesi eklenerek yapılır:

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

Üyeleri yeniden adlandırma

Android için .NET, Java ile konuşmak için özgün Java Yerel Arabirimi (JNI) adlarını gerektirdiğinden üyeleri yeniden adlandırma işlemi doğrudan api.xml dosyasını düzenleyerek yapılamaz. Bu nedenle, //class/@name özniteliği değiştirilemez; değiştiriliyorsa bağlama çalışmaz.

türünü android.Manifestyeniden adlandırmak istediğimiz durumu düşünün. Bunu başarmak için api.xml doğrudan düzenlemeyi ve sınıfı şu şekilde yeniden adlandırmayı deneyebiliriz:

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

Bu, Bağlama Oluşturucusunun sarmalayıcı sınıfı için aşağıdaki C# kodunu oluşturmasını sağlar:

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

Sarmalayıcı sınıfının olarak yeniden adlandırıldığını NewName, özgün Java türünün ise hala Manifestolduğuna dikkat edin. Android için .NET bağlama sınıfının üzerindeki android.Manifestherhangi bir yönteme erişmesi artık mümkün değildir; sarmalayıcı sınıfı mevcut olmayan bir Java türüne bağlıdır.

Sarmalanan bir türün (veya yöntemin) "yönetilen" adını düzgün bir şekilde değiştirmek için, özniteliğin managedName bu örnekte gösterildiği gibi ayarlanması gerekir:

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

Herhangi bir üyeyi, örneğin sınıflar, arabirimler, yöntemler ve parametreler, yeniden adlandırmaya çalışırken managedName kullanılması gerekir.

Sarmalayıcı sınıflarını EventArg yeniden adlandırma

Android için .NET bağlama oluşturucu bir onXXX için bir ayarlayıcı yöntemi tanımladığında, Java tabanlı dinleyici deseni için .NET aromalı API'yi desteklemek üzere bir C# olayı ve EventArgs alt sınıfı oluşturulur. Örneğin, aşağıdaki Java sınıfını ve yöntemini göz önünde bulundurun:

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

Android için .NET, setter yöntemindeki on ön ekini kaldırır ve bunun yerine 2DSignNextManuever'i alt sınıf adı için temel olarak kullanır. Alt sınıf şuna benzer bir adla adlandırılır:

NavigationManager.2DSignNextManueverEventArgs

Bu yasal bir C# sınıf adı değildir. Bu sorunu düzeltmek için bağlama yazarının özniteliğini argsType kullanması ve alt sınıf için EventArgs geçerli bir C# adı sağlaması gerekir:

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

Desteklenen öznitelikler

Aşağıdaki bölümlerde Java API'lerini dönüştürmeye yönelik bazı öznitelikler açıklanmaktadır.

argsType

Bu öznitelik, Java dinleyicilerini desteklemek için oluşturulacak alt sınıfı adlandırmak EventArg için ayarlayıcı yöntemlerine yerleştirilir. Bu, bu kılavuzdaki EventArg Sarmalayıcı Sınıflarını Yeniden Adlandırma bölümünde daha ayrıntılı olarak açıklanmıştır.

etkinlikAdı

Bir olay için bir ad belirtir. Ad boşsa, olay oluşturmayı engeller. Bu, EventArg Sarmalayıcı Sınıflarını Yeniden Adlandırma bölümünde daha ayrıntılı olarak açıklanmıştır.

managedName

Bu, bir paketin, sınıfın, yöntemin veya parametrenin adını değiştirmek için kullanılır. Örneğin, Java sınıfının MyClass adını NewClassName olarak değiştirmek için:

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

Sonraki örnekte yönteminin java.lang.object.toStringJava.Lang.Object.NewManagedNameolarak yeniden adlandırılması için bir XPath ifadesi gösterilmektedir:

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

yönetilenTür

managedType bir yöntemin dönüş türünü değiştirmek için kullanılır. Bazı durumlarda Bağlama Oluşturucu bir Java yönteminin dönüş türünü yanlış çıkarsar ve bu da derleme zamanı hatasına neden olur. Bu durumda olası çözümlerden biri yöntemin dönüş türünü değiştirmektir.

Örneğin, Bağlamalar Oluşturucu, Java yönteminin bir int döndürüp Object parametre olarak alması gerektiğine inanıyor ve bu da şu hata iletisiyle sonuçlanıyor: Hata CS0535: 'DE.Neom.Neoreadersdk.Resolution', 'Java.Lang.IComparable.CompareTo(Java.Lang.Object)' arabirim üyesini uygulamaz. Oluşturulan C# yönteminin ilk parametresinin türünü bir DE.Neom.Neoreadersdk.Resolution'den bir Java.Lang.Object'e değiştirme işlemini gösteren aşağıdaki kod parçacığı:

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

YönetilenDönüş

Bir yöntemin dönüş türünü değiştirir. Bu, dönüş özniteliğini değiştirmez (dönüş özniteliklerindeki değişiklikler JNI imzasında uyumsuz değişikliklere neden olabileceğinden). Aşağıdaki örnekte, append yönteminin dönüş türü SpannableStringBuilder yerine IAppendable olarak değiştirilmiştir:

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

Gizlenmiş

Java kitaplıklarını gizleyen araçlar, Android için .NET Bağlama Oluşturucu'ya ve C# sarmalayıcı sınıfları oluşturma özelliğine müdahale edebilir. Karartılmış sınıfların özellikleri şunlardır:

  • Sınıf adı bir $içerir; örneğin , a$.class
  • Sınıf adı tamamen küçük harfli karakterlerden oluşur, yani a.class

Bu kod parçacığı, "belirsiz" bir C# türü oluşturmaya yönelik bir örnektir:

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

propertyName

Bu öznitelik, yönetilen özelliğin adını değiştirmek için kullanılabilir.

Özel bir kullanım propertyName örneği, Java sınıfının yalnızca bir alan için ayarlayıcı yöntemine sahip olduğu durumu içerir. Bu durumda Bağlama Oluşturucu, .NET'te önerilmez olan bir salt yazma özelliği oluşturmak isteyebilir. Aşağıdaki kod parçacığı, öğesini boş bir dizeye ayarlayarak propertyName .NET özelliklerinin nasıl "kaldırılacağını" gösterir:

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

Ayarlayıcı ve getter yöntemlerinin Bağlama Oluşturucu tarafından oluşturulmaya devam edeceğine, yalnızca bir .NET özelliğine dönüştürülmeyeceklerine dikkat edin.

gönderen

Bir yöntem bir olaya eşlendiğinde, hangi parametresinin sender parametresi olması gerektiğini belirtir. Değer true veya false olabilir. Örneğin:

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

görünürlük

Bu öznitelik bir sınıfın, yöntemin veya özelliğin görünürlüğünü değiştirmek için kullanılır. Örneğin, karşılık gelen C# sarmalayıcısının protectedolması için bir public Java yöntemini yükseltmek gerekebilir:

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