Вызов кода платформы
В ситуациях, когда .NET многоплатформенный пользовательский интерфейс приложения (.NET MAUI) не предоставляет интерфейсы API для доступа к определенным API платформы, вы можете написать собственный код для доступа к необходимым API платформы. Для этого требуются знания об API iOS и MacCatalyst Apple, API-интерфейсах Google Для Android и API Windows App SDK Корпорации Майкрософт.
Код платформы можно вызывать из кроссплатформенного кода с помощью условной компиляции или с помощью разделяемых классов и разделяемых методов.
Условная компиляция
Код платформы можно вызывать из кроссплатформенного кода с помощью условной компиляции для разных платформ.
В следующем примере показано перечисление DeviceOrientation
, которое будет использоваться для указания ориентации устройства:
namespace InvokePlatformCodeDemos.Services
{
public enum DeviceOrientation
{
Undefined,
Landscape,
Portrait
}
}
Для получения ориентации устройства требуется написание кода платформы. Это можно сделать, написав метод, использующий условную компиляцию для различных платформ:
#if ANDROID
using Android.Content;
using Android.Views;
using Android.Runtime;
#elif IOS
using UIKit;
#endif
using InvokePlatformCodeDemos.Services;
namespace InvokePlatformCodeDemos.Services.ConditionalCompilation
{
public class DeviceOrientationService
{
public DeviceOrientation GetOrientation()
{
#if ANDROID
IWindowManager windowManager = Android.App.Application.Context.GetSystemService(Context.WindowService).JavaCast<IWindowManager>();
SurfaceOrientation orientation = windowManager.DefaultDisplay.Rotation;
bool isLandscape = orientation == SurfaceOrientation.Rotation90 || orientation == SurfaceOrientation.Rotation270;
return isLandscape ? DeviceOrientation.Landscape : DeviceOrientation.Portrait;
#elif IOS
UIInterfaceOrientation orientation = UIApplication.SharedApplication.StatusBarOrientation;
bool isPortrait = orientation == UIInterfaceOrientation.Portrait || orientation == UIInterfaceOrientation.PortraitUpsideDown;
return isPortrait ? DeviceOrientation.Portrait : DeviceOrientation.Landscape;
#else
return DeviceOrientation.Undefined;
#endif
}
}
}
В этом примере реализации GetOrientation
метода платформы предоставляются для Android и iOS. На других платформах DeviceOrientation.Undefined
возвращается. Кроме того, вместо возврата DeviceOrientation.Undefined
можно создать исключение PlatformNotSupportedException
, указывающее платформы, для которых предоставляются реализации:
throw new PlatformNotSupportedException("GetOrientation is only supported on Android and iOS.");
Затем DeviceOrientationService.GetOrientation
метод можно вызвать из кроссплатформенного кода, создав экземпляр объекта и вызвав его операцию:
using InvokePlatformCodeDemos.Services;
using InvokePlatformCodeDemos.Services.ConditionalCompilation;
...
DeviceOrientationService deviceOrientationService = new DeviceOrientationService();
DeviceOrientation orientation = deviceOrientationService.GetOrientation();
Во время сборки система сборки использует условную компиляцию для целевого кода платформы Android и iOS на правильную платформу.
Дополнительные сведения об условной компиляции см. в разделе "Условная компиляция".
Разделяемые классы и методы
Проект приложения MAUI .NET содержит папку "Платформы" с каждой дочерней папкой, представляющей платформу, которая .NET MAUI может быть нацелена на:
Папки для каждой целевой платформы содержат код для конкретной платформы, который запускает приложение на каждой платформе, а также любой дополнительный код платформы, который вы добавляете. Во время сборки система сборки включает только код из каждой папки при сборке для этой конкретной платформы. Например, при сборке для Android файлы в папке "Платформы>Android " будут встроены в пакет приложения, но файлы в других папках платформ не будут. Этот подход использует функцию, называемую мультинацеливанием, для целевых нескольких платформ из одного проекта.
Мультинацеливание можно объединить с частичными классами и частичными методами для вызова функциональных возможностей платформы из кроссплатформенного кода. Этот процесс состоит в следующем:
- Определите кроссплатформенный API как разделяемый класс, который определяет сигнатуры разделяемых методов для любых операций, которые необходимо вызвать на каждой платформе. Дополнительные сведения см. в разделе "Определение кроссплатформенного API".
- Реализуйте кроссплатформенный API для каждой платформы, определив один разделяемый класс и те же сигнатуры разделяемых методов, а также предоставляя реализации метода. Дополнительные сведения см. в разделе "Реализация API для каждой платформы".
- Вызовите кроссплатформенный API, создав экземпляр разделяемого класса и вызвав методы по мере необходимости. Дополнительные сведения см. в разделе "Вызов кроссплатформенного API".
Определение кроссплатформенного API
Чтобы вызвать код платформы из кроссплатформенного кода, сначала необходимо определить кроссплатформенный API как разделяемый класс , который определяет сигнатуры разделяемых методов для любых операций, которые необходимо вызвать на каждой платформе.
В следующем примере показано перечисление DeviceOrientation
, которое будет использоваться для указания ориентации устройства:
namespace InvokePlatformCodeDemos.Services
{
public enum DeviceOrientation
{
Undefined,
Landscape,
Portrait
}
}
В следующем примере показан кроссплатформенный API, который можно использовать для получения ориентации устройства:
namespace InvokePlatformCodeDemos.Services.PartialMethods
{
public partial class DeviceOrientationService
{
public partial DeviceOrientation GetOrientation();
}
}
Разделяемый класс называется DeviceOrientationService
, который включает разделяемый метод с именем GetOrientation
. Файл кода для этого класса должен находиться за пределами папки "Платформы ":
Реализация API для каждой платформы
После определения кроссплатформенного API его необходимо реализовать на всех платформах, на которые вы нацелены, определив один разделяемый класс и одинаковые сигнатуры разделяемых методов, а также предоставляя реализации метода.
Реализации платформы должны размещаться в правильных дочерних папках платформ , чтобы гарантировать, что система сборки пытается создавать код платформы только при сборке для конкретной платформы. В следующей таблице перечислены расположения папок по умолчанию для реализаций платформы.
Платформа | Папка |
---|---|
Android | Платформ>Android |
iOS | Платформ>Ios |
MacCatalyst | Платформ>MacCatalyst |
Tizen | Платформ>Tizen |
Windows | Платформ>Windows |
Важно!
Реализации платформы должны находиться в одном пространстве имен и том же классе, в который был определен кроссплатформенный API.
На следующем снимке экрана показаны DeviceOrientationService
классы в папках Android и iOS :
Кроме того, можно выполнить многоцелевой выбор на основе собственных критериев имени файла и папки, а не с помощью папок Платформ . Дополнительные сведения см. в разделе "Настройка многонацеливания".
Android
В следующем примере показана GetOrientation
реализация метода в Android:
using Android.Content;
using Android.Runtime;
using Android.Views;
namespace InvokePlatformCodeDemos.Services.PartialMethods;
public partial class DeviceOrientationService
{
public partial DeviceOrientation GetOrientation()
{
IWindowManager windowManager = Android.App.Application.Context.GetSystemService(Context.WindowService).JavaCast<IWindowManager>();
SurfaceOrientation orientation = windowManager.DefaultDisplay.Rotation;
bool isLandscape = orientation == SurfaceOrientation.Rotation90 || orientation == SurfaceOrientation.Rotation270;
return isLandscape ? DeviceOrientation.Landscape : DeviceOrientation.Portrait;
}
}
iOS
В следующем примере показана реализация метода в GetOrientation
iOS:
using UIKit;
namespace InvokePlatformCodeDemos.Services.PartialMethods;
public partial class DeviceOrientationService
{
public partial DeviceOrientation GetOrientation()
{
UIInterfaceOrientation orientation = UIApplication.SharedApplication.StatusBarOrientation;
bool isPortrait = orientation == UIInterfaceOrientation.Portrait || orientation == UIInterfaceOrientation.PortraitUpsideDown;
return isPortrait ? DeviceOrientation.Portrait : DeviceOrientation.Landscape;
}
}
Вызов кроссплатформенного API
После предоставления реализаций платформы API можно вызвать из кроссплатформенного кода, создав экземпляр объекта и вызвав его операцию:
using InvokePlatformCodeDemos.Services;
using InvokePlatformCodeDemos.Services.PartialMethods;
...
DeviceOrientationService deviceOrientationService = new DeviceOrientationService();
DeviceOrientation orientation = deviceOrientationService.GetOrientation();
Во время сборки система сборки будет использовать несколько целевых объектов для объединения кроссплатформенного разделяемого класса с частичным классом для целевой платформы и его сборки в пакет приложения.
Настройка многоцелевой настройки
.NET приложения MAUI также могут быть многоцелыми на основе собственных критериев имени файла и папки. Это позволяет структурировать проект приложения MAUI .NET таким образом, чтобы код платформы не помещался в дочерние папки папки платформы.
Например, стандартный шаблон с несколькими целевыми объектами — включить платформу в качестве расширения в имя файла кода платформы. Система сборки может быть настроена для объединения кроссплатформенных разделяемых классов с разделяемыми классами платформы на основе этого шаблона:
Еще одним стандартным шаблоном многонацеливания является включение платформы в качестве имени папки. Система сборки может быть настроена для объединения кроссплатформенных разделяемых классов с разделяемыми классами платформы на основе этого шаблона:
Дополнительные сведения см. в разделе "Настройка многонацеливания".