Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
Вызываемые оболочки Android (ACW) требуются при каждом вызове управляемого кода средой выполнения Android. Эти оболочки являются обязательными, так как в среде выполнения не существует способа регистрации классов с помощью ART (среда выполнения Android). (В частности, функция JNI DefineClass() не поддерживается средой выполнения Android.} Таким образом вызываемые оболочки Android компенсируют отсутствие поддержки регистрации типа среды выполнения.
Код Android должен каждый раз выполнять virtual или метод интерфейса, который является overridden или реализован в управляемом коде, а Xamarin.Android — предоставить прокси-сервер Java, чтобы этот метод был отправлен в соответствующий управляемый тип. Эти типы прокси Java — это код Java, имеющий тот же базовый класс и список интерфейсов Java, что и управляемый тип, реализующий те же конструкторы и объявляющий любые переопределенные базовые классы и методы интерфейса.
Вызываемые оболочки Android создаются программой monodroid.exe во время процесса сборки: они создаются для всех типов, которые (прямо или косвенно) наследуют Java.Lang.Object.
Имя вызываемой программы-оболочки
Имена пакетов для вызываемых оболочек Android основаны на MD5SUM имени экспортируемого типа с указанием сборки. Такая методика именования позволяет сделать то же полное имя типа доступным для разных сборок без введения ошибки упаковки.
Из-за этой схемы именования MD5SUM вы не можете напрямую обращаться к типам по имени. Например, следующая команда adb не будет работать, так как имя типа my.ActivityType не создается по умолчанию:
adb shell am start -n My.Package.Name/my.ActivityType
Кроме того, если вы попытаетесь сослаться на тип по имени, вы можете заметить следующие ошибки:
java.lang.ClassNotFoundException: Didn't find class "com.company.app.MainActivity"
on path: DexPathList[[zip file "/data/app/com.company.App-1.apk"] ...
Если вы требуете доступ к типам по имени, имя для этого типа можно объявить в объявлении атрибута. Например, ниже приведен код, объявляющий действие с полным именем My.ActivityType:
namespace My {
[Activity]
public partial class ActivityType : Activity {
/* ... */
}
}
Для свойства ActivityAttribute.Name можно задать явное объявление имени этого действия:
namespace My {
[Activity(Name="my.ActivityType")]
public partial class ActivityType : Activity {
/* ... */
}
}
После добавления этого параметра свойства my.ActivityType к нему можно получить доступ по имени из внешнего кода и из сценариев adb. Атрибут Name можно задать для множества различных типов, включая Activity, Application, Service, BroadcastReceiver и ContentProvider.
- ActivityAttribute.Name
- ApplicationAttribute.Name
- ServiceAttribute.Name
- BroadcastReceiverAttribute.Name
- ContentProviderAttribute.Name
В Xamarin.Android 5.0 введено именование ACW на базе MD5SUM. Дополнительные сведения об именовании атрибутов см. в RegisterAttribute.
Реализация интерфейсов
Иногда может потребоваться реализовать интерфейс Android, например Android.Content.IComponentCallbacks.
Поскольку все классы и интерфейсы Android расширяют интерфейс Android.Runtime.IJavaObject, возникает вопрос: как реализовать IJavaObject?
Ответ на этот вопрос дан выше: причина, по которой все типы Android должны реализовать IJavaObject, заключается в том, что Xamarin.Android имеет вызываемую программу-оболочку Android для предоставления Android, т. е. прокси-сервер Java для данного типа. Поскольку monodroid.exe ищет только подклассы Java.Lang.Object, а Java.Lang.Object реализует IJavaObject, ответ очевиден: подкласс Java.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...
}
}
Сведения о реализации
Оставшаяся часть этой страницы предоставляет сведения о реализации, которые могут быть изменены без предварительного уведомления (и предоставляются здесь только потому, что разработчикам интересно, как это происходит).
Например, рассмотрим приведенный ниже исходный код C#.
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 создаст следующую вызываемую оболочку Android:
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);
}
Обратите внимание, что базовый класс сохраняется, и для каждого метода, переопределяемого в управляемом коде, предоставляются объявления методов native.