Продолжаем анализ архитектуры мобильных кроссплатформенных инструментов. Сегодня на повестке дня фреймворки Xamarin и Qt. Напомним, что в первой части мы рассмотрели общие архитектурные паттерны кроссплатформенных фреймворков, а также архитектуры PhoneGap и ReactNative.
Данная статья является сокращенной версией руководства, доступного по ссылке в конце.
Передаю слово Вячеславу Черникову.
Qt
Qt является одним из старейших кроссплатформенных фреймворков и используется очень широко для разработки embedded и десктопных приложений. Архитектура Qt позволяет портировать его в те операционные системы, которые имеют API для C++. И iOS, и Android (NDK), и Windows такой возможностью обладают, хотя и все со своими особенностями.
Один из главных плюсов Qt — собственная эффективная система отрисовки пользовательского интерфейса либо на базе растрового движка (например, CoreGraphics в iOS), либо на базе Open GL (ES). Именно это и делает фреймворк портируемым. То есть в Qt используются свои механизмы отрисовки UI — приложение будет выглядеть нативным настолько, насколько вы его сами стилизуете.
Как видим, на iOS используются стандартные модули CoreGraphics и UIKit для отрисовки пользовательского интерфейса. В Android ситуация чуть посложнее, так как Qt использует механизмы NDK для отрисовки UI, а для доступа к Java API и управления приложением используется уже знакомый нам мост JNI. Также в iOS и Android может использоваться Open GL ES для отрисовки QML или работы с 3D.
В Windows имеется прямой доступ к C++ API и все работало бы отлично, если бы не необходимость использовать конвертацию вызовов Open GL ES в вызовы DirectX (растровая отрисовка не удовлетворяет по производительности, а Open GL ES нет в Windows UWP). В этом помогает библиотека ANGLE.
Интерфейс приложений на основе Qt не является нативным, а только делается похожим на него с помощью стилизации.
В целом Qt можно было бы рекомендовать как вещь в себе — только готовые модули самого фреймворка плюс платформонезависимые библиотеки на C++. Но в реальных проектах его использовать будет очень непросто — неродной UI, отсутствуют сторонние компоненты (только библиотеки “из коробки”), возникают сложности при сборке и отладке приложения, а также при доступе к нативной функциональности. Из плюсов — высокая производительность кода на C++.
Итак, Qt можно рекомендовать для разработки приложений под iOS, Android и Windows UWP только в том случае, если у вас уже имеются большой опыт работы с Qt и понимание непростых системных механизмов. Стоит учитывать, что интерфейс в любом случае может быть только похожим на родной.
Xamarin
Xamarin сейчас доступен в open source и появился в качестве развития проекта Mono, открытой реализации инфраструктуры .NET для Unix-систем. Изначально Mono поддерживался компанией Novell и позволял запускать .NET-приложения в Linux и других открытых ОС.
Для взаимодействия с родными (для C) интерфейсами операционных систем в Mono используется механизм P/Invoke. На основе Mono были созданы фреймворки MonoTouch и MonoDroid, которые затем переименовали в Xamarin.iOS и Xamarin.Android, и теперь вместе называют “классическим Xamarin” (Xamarin Classic).
Классический Xamarin предоставляет полный доступ к нативным API, то есть можно создавать нативные приложения iOS/Android с помощью C# без единой строчки на Objective C и Java. Нативные библиотеки подключаются через механизм байндинга (Native Library Binding). Взаимодействие с ОС происходит через мост и механизм оберток (wrappers), однако нет необходимости сериализовать данные, так как осуществляется автоматический маршалинг и есть возможность прямой передачи ссылок между средами Mono Managed и Native. Можно также использовать большое количество .NET-библиотек из NuGet.
Инфраструктура .NET/Mono предполагает использование JIT по аналогии с Java, когда приложение упаковывается в промежуточный байт-код и уже потом компилируется во время исполнения. Но из-за ограничений iOS нет возможности использовать JIT, и поэтому байт-код Xamarin.iOS-приложений компилируется в нативный бинарный и статически линкуется вместе с библиотеками. Такая компиляция называется AOT (Ahead Of Time) и является обязательной в Xamarin.iOS. В Xamarin.Android же помимо AOT доступен и режим JIT, когда виртуальное окружение Mono работает параллельно с Dalvik/ART.
Как видим, общая база кода между платформами ограничивается бизнес-логикой и механизмами работы с данными. К сожалению, UI и платформенную функциональность приходится реализовывать отдельно для каждой платформы. В результате шарить можно не более 30%-40% от общей базы кода мобильных приложений. Для достижения большего результата необходимо использовать Xamarin.Forms, о котором мы расскажем в Главе 3.5.
Ключевым преимуществом классического Xamarin является использование языка C# для всего кода и, как следствие, разработчиков, которые уже хорошо знакомы с .NET. Также обязательным является хорошее знание и понимание механизмов iOS/Android, их классовых моделей, архитектур, жизненных циклов объектов и умение читать примеры на Objective C и Java.
Производительность C#-кода сопоставима с производительностью нативного кода в iOS/Android, но при взаимодействии с ОС используется мост, который может замедлять приложение при неэффективном использовании.
Классический Xamarin является достаточно зрелым решением и обеспечивает максимально близкий к нативному опыт разработки для C#-программистов и использованием привычных инструментов вроде Visual Studio.
Итак, если стоит задача реализовать полностью нативное приложение и при этом имеются опытные C#-разработчики, то Xamarin может стать хорошим выбором для широкого спектра задач, как больших (более 40 экранов), так и маленьких (до 10 экранов).
Xamarin.Forms
Если у вас стоит цель максимизировать общую базу кода, то классический Xamarin здесь явно проигрывает всем остальным фреймворкам (PhoneGap, ReactNative, Qt и их аналогам). Это понимали и в самом Xamarin, поэтому выпустили решение, позволяющее использовать единое описание UI и простые механизмы доступа к платформенным фичам — Xamarin.Forms.
Библиотека Xamarin.Forms работает поверх описанного ранее классического Xamarin и фактически предоставляет механизмы виртуализации пользовательского интерфейса и дополнительную инфраструктуру.
Для того, чтобы лучше понять, как работает XF, давайте рассмотрим простую кнопку. Одним из базовых механизмов являются рендереры (renderers), благодаря которым при отображении кнопки Xamarin.Forms фактически на экран добавляется нативный контрол, а свойства XF-кнопки динамически пробрасываются в свойства нативной кнопки на каждой платформе. В ReactNative используются похожие механизмы.
Общая (shared) часть на Xamarin.Forms обычно реализуется в виде библиотеки (Portable/PCL или .NET Standard) и имеет доступ к базе компонентов в NuGet. Платформенная часть реализуется на базе Xamarin Classic и имеет полный доступ к нативному API, а также возможность подключения сторонних библиотек. При этом общий процент кода между платформами обычно доходит до 85%. Также Xamarin.Forms можно использовать в режиме Embedded для создания отдельных экранов и View внутри приложений на классическом Xamarin.iOS и Xamarin.Android.
Итак, Xamarin.Forms можно рекомендовать для быстрой разработки прототипов на C#, однако Xamarin.Forms также можно использовать для корпоративных и бизнес-приложений любого масштаба (80 и более экранов). Внешний вид, производительность и поведение приложений будет полностью нативным, но стоит не забывать об эффективном взаимодействии с операционной системой через мост.
Заключение
В нашей статье мы рассмотрели особенности популярных мобильных фреймворков с точки зрения архитектуры. Сами по себе кроссплатформенные приложения являются очень быстрыми и сопоставимы с нативными, однако необходимость использования моста немного снижает скорость при взаимодействии с родными API.
Общий вывод: во всех популярных кроссплатформенных фреймворках используется мост, снижающий скорость взаимодействия с нативной частью. Следует оптимизировать узкие места (специфичные для каждого фреймворка) при создании пользовательского интерфейса. Финальный выбор фреймворка будет зависеть от имеющихся в команде компетенций и требований к конечному результату.
При выборе фреймворка стоит учитывать не только язык программирования, но и необходимый уровень знаний целевых операционных систем (iOS, Android, Windows), а также опираться на опыт вашей команды разработчиков. Например, при использовании PhoneGap можно обойтись поверхностными знаниями ОС, если не требуется вручную реализовать платформенную функциональность. А для Xamarin Classic придется стать экспертом в iOS и/или Android.
В качестве итога давайте соберем все рекомендации по выбору фреймворков в одном месте:
- PhoneGap — если вам необходимо быстро сделать простое приложение или прототип и в команде есть опыт разработки одностраничных веб-приложений (HTML, JavaScript, CSS). В большинстве случаев можно обойтись готовыми плагинами для нативной функциональности. Из минусов — неродной интерфейс с частыми подергиваниями и залипаниями и непростой доступ к нативной части. Процент разделяемого кода — до 95%.
- ReactNative — отлично подойдет для опытных JavaScript-разработчиков и команд, но потребует достаточно хорошего знания iOS Objective C API и Android Java API. Приложения выглядят и работают нативно, но также стоит учитывать юность фреймворка. Процент разделяемого кода — до 90%.
- Xamarin Classic — если у вас есть опытные C#-разработчики, то им потребуется глубоко освоить iOS и Android. Приложения будут полностью нативными, хотя и написаны на C#. Объем общей базы кода в редких случаях превышает 40%.
- Xamarin.Forms — подойдет опытным C#-разработчикам, особенно со знанием XAML. Для приложений с простым интерфейсом (стандартные контролы или готовые компоненты) не потребуется глубоких знаний iOS/Android/Windows. Процент разделяемого кода — до 90%.
- Qt — этот фреймворк можно рекомендовать только в случае, если у вас уже есть существующее приложение (например, embedded) и его необходимо запустить на iOS/Android. Высокие требования к квалификации разработчиков, непростой доступ к нативной функциональности и неродной UI являются заметными минусами фреймворка. Процент разделяемого кода может доходить до 95%.
Полную версию руководства вы можете найти на GitBook.
31 октября Вячеслав также будет выступать на нашем вебинаре Mobile DevOps для Xamarin-разработчиков, ускоряем тестирование и поставку. Участие как всегда бесплатное.
Напоминаем, что во второй части обзора мы подробнее остановимся на Xamarin и Qt, а также общих рекомендациях в выборе фреймворка. Оставайтесь на связи и задавайте свои вопросы в комментариях!
Об авторе
Вячеслав Черников — руководитель отдела разработки компании Binwell, Microsoft MVP и Xamarin Certified Developer. В прошлом — один из Nokia Champion и Qt Certified Specialist, в настоящее время — специалист по платформам Xamarin и Azure. В сферу mobile пришел в 2005 году, с 2008 года занимается разработкой мобильных приложений: начинал с Symbian, Maemo, Meego, Windows Mobile, потом перешел на iOS, Android и Windows Phone. Статьи Вячеслава вы также можете прочитать в блоге на Medium.
Другие статьи автора вы можете найти в нашей колонке #xamarincolumn.
Оставайтесь на связи и задавайте свои вопросы в комментариях!
Автор: Schvepsss