Вызов кода платформы

Просмотрите пример. Обзор примера

В ситуациях, когда пользовательский интерфейс многоплатформенного приложения .NET (.NET MAUI) не предоставляет интерфейсы API для доступа к определенным API платформы, можно написать собственный код для доступа к необходимым API платформы. Для этого требуется знание API iOS и MacCatalyst Apple, API Android Google и API-интерфейсов Microsoft 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 компилировался на соответствующую платформу.

Дополнительные сведения об условной компиляции см. в разделе "Условная компиляция".

Частичные классы и методы

Проект приложения .NET MAUI содержит папку "Платформы" с каждой дочерней папкой, представляющей платформу, предназначенную для .NET MAUI:

Снимок экрана папок платформы.

Папки для каждой целевой платформы содержат код для конкретной платформы, который запускает приложение на каждой платформе, а также любой дополнительный добавленный код платформы. Во время сборки система сборки включает только код из каждой папки при сборке для конкретной платформы. Например, при сборке для Android файлы в папке Platform>Android будут встроены в пакет приложения, но файлы в других папках Платформ не будут. Этот подход использует функцию, называемую мульти-таргетинг, для нацеливания на несколько платформ из одного проекта.

Многонацеленная обработка может сочетаться с частичными классами и частичными методами для вызова функциональных возможностей платформы из кроссплатформенного кода. Процесс выполнения этого состоит в следующем:

  1. Определите кроссплатформенный API как частичный класс, который определяет сигнатуры частичных методов для любых операций, которые необходимо вызвать на каждой платформе. Дополнительные сведения см. в разделе "Определение кроссплатформенного API".
  2. Реализуйте кроссплатформенный API для каждой платформы, определяя один и тот же частичный класс и те же сигнатуры частичных методов, а также предоставляя реализации метода. Дополнительные сведения см. в разделе "Реализация API для каждой платформы".
  3. Вызов кроссплатформенного 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. Файл кода для этого класса должен находиться вне папки Platform :

Класс DeviceOrientationService на снимке экрана папки

Реализация API для каждой платформы

После определения кроссплатформенного API его необходимо реализовать на всех платформах, на которые вы нацелены, определив один и тот же частичный класс и те же сигнатуры частичных методов, а также предоставляя реализации метода.

Реализации платформы должны размещаться в правильных дочерних папках Платформ , чтобы гарантировать, что система сборки пытается создавать код платформы только при создании конкретной платформы. В следующей таблице перечислены расположения папок по умолчанию для реализаций платформы:

Platform Folder
Андроид Платформы>Android
iOS Платформ>Ios
Маккаталитт Платформы>MacCatalyst
Tizen Платформы>Tizen
Виндоус Платформы>Windows

Это важно

Реализации платформы должны находиться в одном пространстве имен и том же классе, в который был определен кроссплатформенный API.

На следующем снимке экрана показаны DeviceOrientationService классы в папках Android и iOS :

Классы DeviceOrientationService на снимке экрана папки

Кроме того, можно выполнять многонацелие на основе собственных критериев имени файла и папки, а не с помощью папок Платформ . Дополнительные сведения см. в разделе "Настройка многонацеливания".

Андроид

В следующем примере показана реализация метода 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 также могут быть многоцелыми на основе собственных условий имени файла и папок. Это позволяет структурировать проект приложения .NET MAUI, чтобы не помещать код платформы в дочерние папки папки "Платформы ".

Например, стандартный шаблон мульти-таргетинга — включить платформу как расширение в имя файла для кода платформы. Система сборки может быть настроена для объединения кроссплатформенных частичных классов с частичными классами платформы на основе этого шаблона:

Классы DeviceOrientationService с использованием мультинаправленности на основе файлов.

Другой стандартный шаблон многоцелевого использования заключается в том, чтобы использовать имя платформы в качестве имени папки. Система сборки может быть настроена для объединения кроссплатформенных частичных классов с частичными классами платформы на основе этого шаблона:

Классы DeviceOrientationService, использующие мультитаргетинг на основе папок.

Дополнительные сведения см. в разделе "Настройка многонацеливания".