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

Просмотрите пример. Просмотр примера

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

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

  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. Файл кода для этого класса должен находиться за пределами папки "Платформы ":

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

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

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

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

Платформа Папка
Android Платформ>Android
iOS Платформ>Ios
MacCatalyst Платформ>MacCatalyst
Tizen Платформ>Tizen
Windows Платформ>Windows

Важно!

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

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

Снимок экрана классов DeviceOrientationService в папке

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

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 таким образом, чтобы код платформы не помещался в дочерние папки папки платформы.

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

Классы DeviceOrientationService с несколькими целевыми объектами на основе имени файла.

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

Классы DeviceOrientationService с использованием мультинацеливания на основе папок.

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