Sınırlamalar
Android 'deki uygulamalar, derleme işlemi sırasında Java proxy türleri üretmesini gerektirdiğinden, çalışma zamanında tüm kodları oluşturmak mümkün değildir.
Bunlar, masaüstü Mono ile karşılaştırıldığında Xamarin. Android kısıtlamalarıdır:
Sınırlı dinamik dil desteği
Android çağrılabilir sarmalayıcılarda , Android çalışma zamanının yönetilen kodu çağırması gereken her zaman gereklidir. Android çağrılabilir sarmalayıcılar, Il 'nin statik analizine dayanarak derleme zamanında oluşturulur. Bunun net sonucu: dinamik dilleri (IronPython, IronRuby, vb. ) kullanamazsınız. gerekli Android çağrılabilir sarmalayıcıları oluşturmak için derleme zamanında bu dinamik türleri Ayıklamadan önce altsınıflama of Java Types 'ın gerekli olduğu herhangi bir senaryoda (dolaylı altsınıflama dahil).
Sınırlı Java üretimi desteği
Java kodunun yönetilen kodu çağırması için Android çağrılabilir sarmalayıcılarını oluşturulması gerekir. Varsayılanolarak, Android çağrılabilir sarmalayıcılar yalnızca (belirli) bir sanal Java yöntemini geçersiz kılan (yani, ) ya da bir Java arabirim yöntemi (arabirim benzer şekilde) uygulayan oluşturucular ve yöntemler içerir Attribute .
4,1 sürümünden önce başka yöntemler bildirilemez. 4,1 sürümü ile, ve ExportField özel öznitelikleri, Android çağrılabilir sarmalayıcı içindeki Java yöntemlerini ve alanlarını bildirmek için kullanılabilir.
Eksik oluşturucular
Oluşturucular, kullanılmadığı takdirde karmaşık kalır ExportAttribute . Android çağrılabilir sarmalayıcı oluşturucuları oluşturmaya yönelik algoritma, şu durumlarda bir Java oluşturucusunun yayınlanacaktır:
- Tüm parametre türleri için bir Java eşlemesi var
- Temel sınıf aynı oluşturucuyu bildirir – bu gereklidir çünkü Android çağrılabilir sarmalayıcı karşılık gelen temel sınıf oluşturucusunu çağırmalıdır; Varsayılan bağımsız değişken kullanılamaz (Java 'da hangi değerlerin kullanılması gerektiğini belirlemenin kolay bir yolu yoktur).
Örneğin, aşağıdaki sınıfı göz önünde bulundurun:
[Service]
class MyIntentService : IntentService {
public MyIntentService (): base ("value")
{
}
}
Bu işlem mükemmel bir şekilde olsa da, yayın Derlemeleriyle elde edilen Android çağrılabilir sarmalayıcı varsayılan bir Oluşturucu içermez. Sonuç olarak, bu hizmeti başlatmaya çalışırsanız (örn. 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, ve ile ExportAttribute belirtmek ve şunları ayarlamak 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
[Export]veya] kullanılamıyor olabilir[ExportField. Bunun denenmeye çalışılması bir hata oluşturacakXA4207.public abstract class Parcelable<T> : Java.Lang.Object, IParcelable { // Invalid; generates XA4207 [ExportField ("CREATOR")] public static IParcelableCreator CreateCreator () { ... }Genel yöntemler, veya kullanamaz
[Export][ExportField]:public class Example : Java.Lang.Object { // Invalid; generates XA4207 [Export] public static void Method<T>(T value) { ... } }[ExportField]Şunu döndüren metotlarda kullanılamazvoid: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. 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, genel bir örnek sınıfındaki başka bir genel (örneklenmiş) sınıftan türetilmiş Üyeler Java. lang. Object olarak sunulur. Örneğin, Android. Content. amacını. GetParcelableExtra yöntemi Java. lang. Object döndürür. Bunun nedeni, silinen Java genel türleri. Bu kısıtlamayı uygulamadığımız bazı sınıflarımız var, ancak bunlar el ile ayarlanırlar.