Aracılığıyla paylaş


Xamarin.Android için Android Çağrılabilen Sarmalayıcılar

Android çalışma zamanı yönetilen kodu her çağırışında Android Çağrılabilir Sarmalayıcılar (ACW) gerekir. Sınıfları çalışma zamanında ART'a (Android çalışma zamanı) kaydetmenin bir yolu olmadığından bu sarmalayıcılar gereklidir. (Özellikle, JNI DefineClass() işlevi Android çalışma zamanı tarafından desteklenmiyor.} Android Çağrılabilen Sarmalayıcılar bu nedenle çalışma zamanı türü kayıt desteğinin olmamasını telafi etti.

Android kodunun overridden yönetilen kodda uygulanan veya uygulanan bir virtual veya arabirim yöntemini yürütmesi gerektiğinde, Xamarin.Android'in bu yöntemin uygun yönetilen türe gönderilmesi için bir Java ara sunucusu sağlaması gerekir. Bu Java proxy türleri, yönetilen türle "aynı" temel sınıfa ve Java arabirim listesine sahip olan, aynı oluşturucuları uygulayan ve geçersiz kılınan temel sınıf ve arabirim yöntemlerini bildiren Java kodulardır.

Android çağrılabilen sarmalayıcılar, derleme işlemi sırasında monodroid.exe programı tarafından oluşturulur: Java.Lang.Object'i devralan (doğrudan veya dolaylı) tüm türler için oluşturulur.

Android Çağrılabilen Sarmalayıcı Adlandırma

Android Çağrılabilen Sarmalayıcılar için paket adları, dışarı aktarılmakta olan türün derleme nitelikli adının MD5SUM değerini temel alır. Bu adlandırma tekniği, aynı tam tür adının paketleme hatası olmadan farklı derlemeler tarafından kullanılabilir hale getirilmesini mümkün kılar.

Bu MD5SUM adlandırma düzeni nedeniyle, türlerinize ada göre doğrudan erişemezsiniz. Örneğin, tür adı my.ActivityType varsayılan olarak oluşturulmadığından aşağıdaki adb komut çalışmaz:

adb shell am start -n My.Package.Name/my.ActivityType

Ayrıca, bir türe ada göre başvurmaya çalışırsanız aşağıdaki gibi hatalar görebilirsiniz:

java.lang.ClassNotFoundException: Didn't find class "com.company.app.MainActivity"
on path: DexPathList[[zip file "/data/app/com.company.App-1.apk"] ...

Türlere ada göre erişime ihtiyacınız varsa, bir öznitelik bildiriminde bu tür için bir ad bildirebilirsiniz. Örneğin, tam adıyla My.ActivityTypebir etkinlik bildiren kod aşağıda verilmiştir:

namespace My {
    [Activity]
    public partial class ActivityType : Activity {
        /* ... */
    }
}

ActivityAttribute.Name özelliği, bu etkinliğin adını açıkça bildirecek şekilde ayarlanabilir:

namespace My {
    [Activity(Name="my.ActivityType")]
    public partial class ActivityType : Activity {
        /* ... */
    }
}

Bu özellik ayarı eklendikten sonra, my.ActivityType dış koddan ve betiklerden adb adla erişilebilir. Name özniteliği , , Application, ServiceBroadcastReceiverve ContentProvidergibi Activitybirçok farklı tür için ayarlanabilir:

MD5SUM tabanlı ACW adlandırması Xamarin.Android 5.0'da kullanıma sunulmuştur. Öznitelik adlandırma hakkında daha fazla bilgi için bkz . RegisterAttribute.

Arabirimleri Uygulama

Bazı durumlarda Android.Content.IComponentCallbacks gibi bir Android arabirimi uygulamanız gerekebilir. Tüm Android sınıfları ve arabirimi Android.Runtime.IJavaObject arabirimini genişlettiklerinden, şu soru ortaya çıkar: nasıl uygularızIJavaObject?

Soru yukarıda yanıtlandı: Tüm Android türlerinin uygulaması IJavaObject gereken neden, Xamarin.Android'in Android'e sağlayabilecek bir Android çağrılabilen sarmalayıcıya sahip olmasıdır, yani verilen tür için java ara sunucusu. monodroid.exe yalnızca alt sınıfları aradığından ve Java.Lang.Object uyguladığından Java.Lang.ObjectIJavaObject, yanıt açıktır: alt sınıfJava.Lang.Object:

class MyComponentCallbacks : Java.Lang.Object, Android.Content.IComponentCallbacks {

    public void OnConfigurationChanged (Android.Content.Res.Configuration newConfig)
    {
        // implementation goes here...
    } 

    public void OnLowMemory ()
    {
        // implementation goes here...
    }
}

Uygulama Ayrıntıları

Bu sayfanın geri kalanında bildirimde bulunulmadan değiştirilebilir uygulama ayrıntıları sağlanır (ve burada sunulur çünkü geliştiriciler neler olup bittiğini merak edecektir).

Örneğin, aşağıdaki C# kaynağı göz önünde bulundurulduğunda:

using System;
using Android.App;
using Android.OS;

namespace Mono.Samples.HelloWorld
{
    public class HelloAndroid : Activity
    {
        protected override void OnCreate (Bundle savedInstanceState)
        {
            base.OnCreate (savedInstanceState);
            SetContentView (R.layout.main);
        }
    }
}

mandroid.exe programı aşağıdaki Android Çağrılabilen Sarmalayıcıyı oluşturur:

package mono.samples.helloWorld;

public class HelloAndroid
    extends android.app.Activity
{
    static final String __md_methods;
    static {
        __md_methods = "n_onCreate:(Landroid/os/Bundle;)V:GetOnCreate_Landroid_os_Bundle_Handler\n" + "";
        mono.android.Runtime.register (
            "Mono.Samples.HelloWorld.HelloAndroid, HelloWorld, Version=1.0.0.0, 
            Culture=neutral, PublicKeyToken=null", HelloAndroid.class, __md_methods);
    }

    public HelloAndroid ()
    {
        super ();
        if (getClass () == HelloAndroid.class)
            mono.android.TypeManager.Activate (
                "Mono.Samples.HelloWorld.HelloAndroid, HelloWorld, Version=1.0.0.0, 
                Culture=neutral, PublicKeyToken=null", "", this, new java.lang.Object[] {  });
    }

    @Override
    public void onCreate (android.os.Bundle p0)
    {
        n_onCreate (p0);
    }

    private native void n_onCreate (android.os.Bundle p0);
}

Temel sınıfın korunduğuna ve native yönetilen kod içinde geçersiz kılınan her yöntem için yöntem bildirimleri sağlandığına dikkat edin.