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.ActivityType
bir 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
, Service
BroadcastReceiver
ve ContentProvider
gibi Activity
birçok farklı tür için ayarlanabilir:
- ActivityAttribute.Name
- ApplicationAttribute.Name
- ServiceAttribute.Name
- BroadcastReceiverAttribute.Name
- ContentProviderAttribute.Name
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.Object
IJavaObject
, 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.