Aracılığıyla paylaş


Sınırlamalar

Android'deki uygulamalar derleme işlemi sırasında Java proxy türleri oluşturmayı gerektirdiğinden, çalışma zamanında tüm kodları oluşturmak mümkün değildir.

Masaüstü Mono ile karşılaştırıldığında Xamarin.Android sınırlamaları şunlardır:

Sınırlı Dinamik Dil Desteği

Android çalışma zamanının yönetilen kodu çağırması gerektiğinde Android çağrılabilir sarmalayıcılar gerekir. Android çağrılabilen sarmalayıcılar, IL'nin statik analizine dayalı olarak derleme zamanında oluşturulur. Bunun net sonucu: Gerekli Android çağrılabilen sarmalayıcıları oluşturmak için derleme zamanında bu dinamik türleri ayıklamanın hiçbir yolu olmadığından Java türlerinin alt sınıflanması gereken herhangi bir senaryoda (dolaylı alt sınıflama dahil) dinamik dilleri (IronPython, IronRuby vb.) kullanamazsınız.

Sınırlı Java Oluşturma Desteği

Java kodunun yönetilen kodu çağırması için Android Çağrılabilen Sarmalayıcıların oluşturulması gerekir. Varsayılan olarak, Android çağrılabilen sarmalayıcılar yalnızca bir sanal Java yöntemini geçersiz kılan (yani, var RegisterAttribute) veya bir Java arabirim yöntemi uygulayan (benzer şekilde arabirimin sahip olduğu Attribute) (belirli) bildirilen oluşturucuları ve yöntemleri içerir.

4.1 sürümünden önce başka yöntem bildirilemedi. 4.1 sürümüyle ve ExportField özel öznitelikleri, ExportAndroid Çağrılabilen Sarmalayıcı içindeki Java yöntemlerini ve alanlarını bildirmek için kullanılabilir.

Eksik oluşturucular

Oluşturucular kullanılmadığı sürece ExportAttribute karmaşık kalır. Android çağrılabilen sarmalayıcı oluşturucuları oluşturmaya yönelik algoritma, aşağıdakiler durumunda bir Java oluşturucunun yayılacağıdır:

  1. Tüm parametre türleri için bir Java eşlemesi vardır
  2. Temel sınıf aynı oluşturucuyu bildirir – Android çağrılabilir sarmalayıcının karşılık gelen temel sınıf oluşturucuyu çağırması gerektiğinden bu gereklidir; varsayılan bağımsız değişkenler kullanılamaz (Java içinde hangi değerlerin kullanılacağını belirlemenin kolay bir yolu olmadığından).

Örneğin, aşağıdaki sınıfı göz önünde bulundurun:

[Service]
class MyIntentService : IntentService {
    public MyIntentService (): base ("value")
    {
    }
}

Bu son derece mantıklı görünse de, Yayın derlemelerinde elde edilen Android çağrılabilen sarmalayıcı varsayılan bir oluşturucu içermez. Sonuç olarak, bu hizmeti başlatmayı denerseniz (örneğin Context.StartService, başarısız olur:

E/AndroidRuntime(31766): FATAL EXCEPTION: main
E/AndroidRuntime(31766): java.lang.RuntimeException: Unable to instantiate service example.MyIntentService: java.lang.InstantiationException: can't instantiate class example.MyIntentService; no empty constructor
E/AndroidRuntime(31766):        at android.app.ActivityThread.handleCreateService(ActivityThread.java:2347)
E/AndroidRuntime(31766):        at android.app.ActivityThread.access$1600(ActivityThread.java:130)
E/AndroidRuntime(31766):        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1277)
E/AndroidRuntime(31766):        at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(31766):        at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime(31766):        at android.app.ActivityThread.main(ActivityThread.java:4745)
E/AndroidRuntime(31766):        at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(31766):        at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(31766):        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
E/AndroidRuntime(31766):        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
E/AndroidRuntime(31766):        at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime(31766): Caused by: java.lang.InstantiationException: can't instantiate class example.MyIntentService; no empty constructor
E/AndroidRuntime(31766):        at java.lang.Class.newInstanceImpl(Native Method)
E/AndroidRuntime(31766):        at java.lang.Class.newInstance(Class.java:1319)
E/AndroidRuntime(31766):        at android.app.ActivityThread.handleCreateService(ActivityThread.java:2344)
E/AndroidRuntime(31766):        ... 10 more

Geçici çözüm, varsayılan bir oluşturucu bildirmek, ile ExportAttributedonatmak ve ayarlamaktır ExportAttribute.SuperStringArgument:

[Service]
class MyIntentService : IntentService {
    [Export (SuperArgumentsString = "\"value\"")]
    public MyIntentService (): base("value")
    {
    }

    // ...
}

Genel C# sınıfları

Genel C# sınıfları yalnızca kısmen desteklenir. Şu sınırlamalar geçerlidir:

  • Genel türler veya [ExportField] kullanamaz[Export]. Bunu yapmaya çalışmak bir XA4207 hata oluşturur.

    public abstract class Parcelable<T> : Java.Lang.Object, IParcelable
    {
        // Invalid; generates XA4207
        [ExportField ("CREATOR")]
        public static IParcelableCreator CreateCreator ()
        {
            ...
    }
    
  • Genel yöntemler veya [ExportField]kullanamaz[Export]:

    public class Example : Java.Lang.Object
    {
    
        // Invalid; generates XA4207
        [Export]
        public static void Method<T>(T value)
        {
            ...
        }
    }
    
  • [ExportField] döndüren voidyöntemlerde kullanılamayabilir:

    public class Example : Java.Lang.Object
    {
        // Invalid; generates XA4208
        [ExportField ("CREATOR")]
        public static void CreateSomething ()
        {
        }
    }
    
  • Genel türlerin örnekleri Java kodundan oluşturulmamalıdır . Bunlar yalnızca yönetilen koddan güvenli bir şekilde oluşturulabilir:

    [Activity (Label="Die!", MainLauncher=true)]
    public class BadGenericActivity<T> : Activity
    {
        protected override void OnCreate (Bundle bundle)
        {
            base.OnCreate (bundle);
        }
    }
    

Kısmi Java Genel Türleri Desteği

Java genel türleri bağlama desteği sınırlıdır. Özellikle, başka bir genel (örneği başlatılmamış) sınıftan türetilen genel bir örnek sınıfındaki üyeler Java.Lang.Object olarak kullanıma sunulur. Örneğin, Android.Content.Intent.GetParcelableExtra yöntemi Java.Lang.Object döndürür. Bunun nedeni, silinen Java genel türleridir. Bu sınırlamayı uygulamayan bazı sınıflarımız var, ancak bunlar el ile ayarlandı.