Mimari
Xamarin. Android Uygulamaları mono yürütme ortamında çalışır. Bu yürütme ortamı, Android Runtime (resım) sanal makinesiyle yan yana çalışır. Her iki çalışma zamanı ortamı da Linux çekirdeğinin üzerinde çalışır ve geliştiricilerin temel sisteme erişmesine izin veren kullanıcı koduna çeşitli API 'Ler sunar. Mono çalışma zamanı C dilinde yazılır.
Temel Linux işletim sistemi tesislerinde erişim sağlamak için System, System.IO, System.net ve .NET sınıf kitaplıklarının geri kalanını kullanabilirsiniz.
Android 'de, ses, grafik, OpenGL ve telefon gibi sistem tesislerinin çoğu doğrudan yerel uygulamalar için kullanılamaz, yalnızca Java. * ad alanları veya Android. * ad alanlarından birinde bulunan Android çalışma zamanı Java API 'leri aracılığıyla sunulur. Mimari kabaca şu şekilde olur:
Xamarin. Android geliştiricileri, bildikleri .NET API 'Lerine (alt düzey erişim için) veya Android çalışma zamanı tarafından kullanıma sunulan Java API 'Lerine köprü sağlayan Android ad alanlarında kullanıma sunulan sınıfları kullanarak işletim sistemindeki çeşitli özelliklere erişir.
Android sınıflarının Android çalışma zamanı sınıflarıyla nasıl iletişim kurduğu hakkında daha fazla bilgi için bkz. API tasarım belgesi.
Uygulama Paketleri
Android uygulama paketleri, . apk dosya UZANTıSıNA sahip ZIP kapsayıcılarıdır. Xamarin. Android uygulama paketleri, aşağıdaki eklemelerle normal Android paketleriyle aynı yapıya ve düzene sahiptir:
Uygulama derlemeleri (Il içeren), derlemeler klasörü içinde sıkıştırılmamış olarak depolanır . Yayın sırasında işlem başlangıcında, . apk, işleme alınan ve derlemeler bellekten yüklenir. Bu, derlemelerin yürütmeden önce ayıklanmak zorunda olmadığından daha hızlı uygulama başlatmaya izin verir.
Note: Derleme . Location ve Assembly. CodeBasegibi bütünleştirilmiş kod konumu bilgileri yayın yapılarıüzerinde kullanılamaz. Ayrı dosya sistemi girişleri olarak bulunmaz ve kullanılabilir bir konuma sahip değildir.
Mono çalışma zamanı içeren yerel kitaplıklar . apk içinde bulunur. Xamarin. Android uygulaması, istenen/hedeflenen Android mimarileri için yerel kitaplıklar içermelidir, örn. armeabi , armeabi-V7A , x86 . Uygun çalışma zamanı kitaplıklarını içermiyorsa Xamarin. Android uygulamaları bir platformda çalıştırılamaz.
Xamarin. Android Uygulamaları, Android 'in yönetilen koda çağrı yapmasına izin vermek için Android çağrılabilir sarmalayıcıları da içerir.
Android Çağrılabilir Sarmalayıcıları
- Android çağrılabilir sarmalayıcılar , Android çalışma zamanının yönetilen kodu çağırması gereken her seferinde kullanılan bir JNI köprüdir. Android çağrılabilir sarmalayıcılar, Sanal yöntemlerin nasıl geçersiz kılınabileceğini ve Java arabirimlerinin nasıl uygulanabileceğini bir şekilde gerçekleştirebilir. Daha fazla bilgi için bkz. Java tümleştirme genel bakış belgesi.
Yönetilen çağrılabilir sarmalayıcılar
Yönetilen çağrılabilir sarmalayıcılar, herhangi bir yönetilen kod için Android kodunu çağırmak ve sanal yöntemleri geçersiz kılma ve Java arabirimlerini uygulama desteği sağlamak için kullanılan bir JNı köprüleridir. Tüm Android. * ve ilgili ad alanları, . jar bağlamasıaracılığıyla oluşturulan, yönetilen çağrılabilir sarmalayıcılardır. Yönetilen çağrılabilir sarmalayıcılar, yönetilen ve Android türleri arasında dönüştürme ve JNı aracılığıyla temeldeki Android Platform yöntemlerini çağırma işleminden sorumludur.
Oluşturulan her yönetilen çağrılabilir sarmalayıcı, Android. Runtime. ıjavaobject. Handle özelliği aracılığıyla erişilebilen bir Java genel başvurusu barındırır. Genel başvurular, Java örnekleri ve yönetilen örnekler arasındaki eşlemeyi sağlamak için kullanılır. Genel başvurular sınırlı bir kaynaktır: Öykünücülerde yalnızca 2000 küresel başvuruların aynı anda var olmasına izin verilir, ancak çoğu donanım aynı anda 52.000 genel başvuruların üzerinde olmasına izin verir.
Genel başvuruların oluşturulup yok edildiğini izlemek için Debug. mono. log sistem özelliğini Grefiçerecek şekilde ayarlayabilirsiniz.
Genel başvurular, yönetilen çağrılabilir sarmalayıcı üzerinde Java. lang. Object. Dispose () çağırarak açık bir şekilde serbest bırakılabilirler. Bu, Java örneği ve yönetilen örnek arasındaki eşlemeyi kaldırır ve Java örneğinin toplanmasını sağlar. Java örneğine yönetilen koddan yeniden erişilirse, bunun için yeni bir yönetilen çağrılabilir sarmalayıcı oluşturulur.
Örnek, örnek olarak iş parçacıkları arasında yanlışlıkla paylaşılırsa, örneğin elden atılması diğer iş parçacıklarından gelen başvuruları etkilerinizde, yönetilen çağrılabilir sarmalayıcıları elden atılırken dikkatli olunması gerekir. En yüksek güvenlik için, yalnızca Dispose() , new her zaman yeni örnekleri ayırmış ve yalnızca new yöntemlerle ayrılmış olan örneklerden Dispose() iş parçacıkları arasında yanlışlıkla örnek paylaşımına neden olabilecek şekilde önbelleğe alınmış örnekler
Yönetilen çağrılabilir sarmalayıcı alt sınıfları
Yönetilen çağrılabilir sarmalayıcı alt sınıfları, tüm "ilginç" uygulamaya özgü mantığının canlı olabileceği yerdir. Bunlara özel Android. app. Activity alt sınıfları (varsayılan proje şablonunda Activity1 türü gibi) dahildir. (Özellikle, bir RegisterAttribute özel özniteliği veya RegisterAttribute Içermeyen herhangi bir Java. lang. Object alt sınıfları vardır . donotgenerateacw , varsayılan değer olan false'dur.)
Yönetilen çağrılabilir sarmalayıcılar gibi, yönetilen çağrılabilir sarmalayıcı alt sınıfları da Java. lang. Object. Handle özelliği aracılığıyla erişilebilen genel bir başvuru içerir. Yönetilen çağrılabilir sarmalayıcılarda olduğu gibi, genel başvurular Java. lang. Object. Dispose ()çağırarak açık bir şekilde serbest bırakılabilirler. Yönetilen çağrılabilir sarmalayıcılarından farklı olarak, örneğinDispose (), örnek oluşturma Java örneği (Android çağrılabilir sarmalayıcı örneği) ve yönetilen örnek arasındaki eşlemeyi bozacaktır.
Java etkinleştirmesi
Java 'dan bir Android çağrılabilir sarmalayıcı (ACW) oluşturulduğunda ACW Oluşturucusu karşılık gelen C# oluşturucusunun çağrılmasına neden olur. Örneğin, MainActivity için ACW, MainActivity'nin varsayılan oluşturucusunu çağıracağı bir varsayılan Oluşturucu içerir. (Bu işlem, ACW oluşturucuları içinde Typemanager. Activate () çağrısıyla yapılır.)
Sonuç olarak başka bir Oluşturucu imzası vardır: (IntPtr, Jnihandlesahiplik) Oluşturucusu. (IntPtr, Jnihandlesahiplik) Oluşturucusu, bir Java nesnesi yönetilen koda gösterildiğinde çağrılır ve JNI tanıtıcısını yönetmek için yönetilen bir çağrılabilir sarmalayıcı oluşturulması gerekir. Bu genellikle otomatik olarak yapılır.
Yönetilen çağrılabilir sarmalayıcı alt sınıfta (IntPtr, Jnihandlesahiplik) oluşturucusunun el ile sağlanması gereken iki senaryo vardır:
Android. app. Application alt sınıflı. Uygulama özeldir; Varsayılan uygulama Oluşturucusu hiçbir şekilde çağrılmaz ve (IntPtr, jnihandlesahiplik) oluşturucusunun sağlanması gerekir.
Temel sınıf oluşturucusundan sanal yöntem çağırma.
(2) bir kaaky soyutlama olduğunu unutmayın. Java 'da, C# ' de olduğu gibi, bir oluşturucudan sanal yöntemlere yapılan çağrılar her zaman en çok türetilen Yöntem uygulamasını çağırır. Örneğin, TextView (Context, AttributeSet, int) Oluşturucusu TextView . defaultmovementmethod özelliğiolarak sınırlanan TextView. getdefaultmovementmethod ()sanal yöntemini çağırır. Bu nedenle, bir Logtextbox türü (1) alt sınıf TextViewIse (2) TextView. defaultmovementmethod ' ı geçersiz KıLıNve (3) XML aracılığıyla bu sınıfın bir örneğini etkinleştirdikten sonra, geçersiz kılınan defaultmovementmethod özelliği, ACW oluşturucusunun yürütme şansı olmadan önce çağrılır ve C# oluşturucusunun yürütme şansı olması durumunda oluşur.
ACW LogTextBox örneği ilk olarak yönetilen kodu girdiğinde ve sonra ACW Oluşturucusu yürütüldüğünde aynı örnekteLogtextbox (Context, ıattributeset, int) oluşturucusunu çağırarak, Logtextview (IntPtr, jnihandlesahiplik) Oluşturucusu aracılığıyla bir örnek logtextbox örneği oluşturulur.
Olay sırası:
Düzen XML 'i bir ContentView'a yüklendi.
Android, düzen nesnesi grafiğini örnekleyerek bir monodroid. apıdemo. logtextbox için ACW, logtextbox için bir örneği başlatır.
Monodroıd. apıdemo. LogTextBox Oluşturucusu, Android. pencere öğesi. TextView oluşturucusunu yürütür.
TextView Oluşturucusu monodroıd. Apıdemo. Logtextbox. getDefaultMovementMethod () öğesini çağırır.
monodroıd. apıdemo. LogTextBox. getDefaultMovementMethod () , Java. lang. Object. GetObject TextView (tanıtıcı, Jnihandlesahiplik. donottransfer) öğesini çağıran TextView.n_GetDefaultMovementMethod () öğesini çağıran LogTextBox.n_getDefaultMovementMethod ( ) öğesini çağırır.
Java. lang. Object. GetObject TextView > ()> için zaten karşılık gelen bir C# örneği olup olmadığını denetler. Varsa, döndürülür. Bu senaryoda olmadığından, Object. GetObject t > () bir tane oluşturması gerekir.
Object. GetObject T > () , > oluşturucusunu arar, çağırır, tanıtıcı ve oluşturulan örnek arasında bir eşleme oluşturur ve oluşturulan örneği döndürür.
TextView.n_GetDefaultMovementMethod ()Logtextbox. DefaultMovementMethod özellik alıcısı 'nı çağırır.
Denetim, yürütmeyi tamamladığında Android. pencere öğesi. TextView oluşturucusuna döner.
Monodroıd. apıdemo. LogTextBox Oluşturucusu yürütülür, Typemanager. Activate () çağrılıyor.
Logtextbox (bağlam, ıattributeset, int) Oluşturucusu içinde oluşturulan aynı örnekte yürütülür (7) .
(IntPtr, Jnihandlesahiplik) Oluşturucusu bulunamazsa, bir System. MissingMethodException] (XREF: System. MissingMethodException) atılır.
Zamanından önce Dispose () çağrıları
JNı tutamacı ile karşılık gelen C# örneği arasında bir eşleme vardır. Java. lang. Object. Dispose () Bu eşlemeyi keser. Bir JNı tanıtıcısı, eşleme kesildikten sonra yönetilen kod girerse, Java etkinleştirmesi gibi görünür ve (IntPtr, Jnihandlesahiplik) Oluşturucusu için denetlenir ve çağrılır. Oluşturucu yoksa, bir özel durum oluşturulur.
Örneğin, aşağıdaki yönetilen çağrılabilir wraper alt sınıfı verildiğinde:
class ManagedValue : Java.Lang.Object {
public string Value {get; private set;}
public ManagedValue (string value)
{
Value = value;
}
public override string ToString ()
{
return string.Format ("[Managed: Value={0}]", Value);
}
}
Bir örnek oluşturuyoruz () ve yönetilen çağrılabilir sarmalayıcının yeniden oluşturulmasına neden olur:
var list = new JavaList<IJavaObject>();
list.Add (new ManagedValue ("value"));
list [0].Dispose ();
Console.WriteLine (list [0].ToString ());
Program zar alacak:
E/mono ( 2906): Unhandled Exception: System.NotSupportedException: Unable to activate instance of type Scratch.PrematureDispose.ManagedValue from native handle 4051c8c8 --->
System.MissingMethodException: No constructor found for Scratch.PrematureDispose.ManagedValue::.ctor(System.IntPtr, Android.Runtime.JniHandleOwnership)
E/mono ( 2906): at Java.Interop.TypeManager.CreateProxy (System.Type type, IntPtr handle, JniHandleOwnership transfer) [0x00000] in <filename unknown>:0
E/mono ( 2906): at Java.Interop.TypeManager.CreateInstance (IntPtr handle, JniHandleOwnership transfer, System.Type targetType) [0x00000] in <filename unknown>:0
E/mono ( 2906): --- End of inner exception stack trace ---
E/mono ( 2906): at Java.Interop.TypeManager.CreateInstance (IntPtr handle, JniHandleOwnership transfer, System.Type targetType) [0x00000] in <filename unknown>:0
E/mono ( 2906): at Java.Lang.Object.GetObject (IntPtr handle, JniHandleOwnership transfer, System.Type type) [0x00000] in <filename unknown>:0
E/mono ( 2906): at Java.Lang.Object._GetObject[IJavaObject] (IntPtr handle, JniHandleOwnership transfer) [0x00000
Alt sınıf bir (IntPtr, Jnihandlesahiplik) Oluşturucusu içeriyorsa, türün Yeni bir örneği oluşturulur. Sonuç olarak, örnek, yeni bir örnek olduğu gibi tüm örnek verilerini "kaybeder" olarak görünür. (Değerin null olduğunu unutmayın.)
I/mono-stdout( 2993): [Managed: Value=]
Yalnızca Java nesnesinin artık kullanılmayacağını bildiğiniz veya alt sınıfta örnek verisi yoksa (IntPtr, Jnihandlesahiplik) Oluşturucu sağlandıysa, yönetilen çağrılabilir sarmalayıcı alt sınıflarının yalnızca Dispose () 'i.
Uygulama başlatma
Bir etkinlik, hizmet vs. başlatıldığında, Android önce etkinliği/hizmeti/vb 'yi barındırmak için çalışan bir işlem olup olmadığını kontrol eder. Böyle bir işlem yoksa, yeni bir işlem oluşturulur, AndroidManifest.xml okunacaktır ve /manifest/Application/@android: Name özniteliğinde belirtilen tür yüklenir ve oluşturulur. Ardından, /manifest/Application/Provider/@android: Name öznitelik değerleri tarafından belirtilen tüm türler örneklenmiştir ve bunun ContentProvider. attachınfo %28) yöntemi çağrıldı. Xamarin. Android bir mono ekleyerek bunu takar . Derleme işlemi sırasında AndroidManifest.xml MonoRuntimeProviderContentProvider . Mono. MonoRuntimeProvider. Attachınfo () yöntemi, mono çalışma zamanının işleme yüklenmesi sorumludur. Bu noktadan önce mono kullanma girişimleri başarısız olur. ( Note: Bu, Android. app. Application alt sınıfının, mono başlatılmadan önce uygulama örneği oluşturulduğu Için (IntPtr, jnihandlesahiplik) Oluşturucususağlaması gereken türlerin nedenidir.)
İşlem başlatma tamamlandıktan sonra, AndroidManifest.xml başlatılacak etkinliğin/hizmetin/vb. sınıf adını bulmak için uyar. Örneğin, /manifest/Application/Activity/@android: Name özniteliği yüklenecek etkinliğin adını belirlemekte kullanılır. Bu tür etkinlikler için Android. app. Activity' yi devralması gerekir.
Belirtilen tür Class. forName () aracılığıyla yüklenir (Bu, türün bir Java türü olmasını gerektirir, bu nedenle Android çağrılabilir sarmalayıcıları) ve örneği oluşturulur. Android çağrılabilir sarmalayıcı örneğinin oluşturulması, karşılık gelen C# türünün bir örneğinin oluşturulmasını tetikler. Android daha sonra Activity. onCreate (paket) çağrılır. Bu, karşılık gelen etkinliğin çağrılmasına neden olur . OnCreate (paket) .
