Данная статья является сокращенной версией руководства, доступного по ссылке в конце.
Передаю слово Вячеславу Черникову.
Введение
Самих фреймворков сейчас существует очень много, но с архитектурной точки зрения они в основном аналогичны PhoneGap, ReactNative и Xamarin, поэтому мы остановимся на этой тройке лидеров. Qt мы добавили в обзор, так как нас часто об этом спрашивают активные Qt-разработчики или те, кто раньше с ним работали и слышали о поддержке iOS и Android.
В качестве целевых платформ мы остановимся на iOS, Android и Windows UWP.
Нативные и кроссплатформенные инструменты разработки
Исторически на рынке компьютеров всегда была конкуренция и каждый производитель предоставлял оптимальный набор так называемых «нативных» (родных) инструментов для разработки приложений под свои операционные системы и устройства. “Нативные” средства разработки обеспечивают оптимальную производительность и доступ к возможностям операционной системы.
Однако часто оказывалось, что эти инструменты были несовместимы друг с другом не только на уровне языка разработки, принятых соглашений и архитектур, но и на уровне механизмов работы с операционной системой и библиотеками. В результате для реализации одних и тех же алгоритмов, пользовательских или бизнес-сценариев требовалось написать приложение для нескольких сред на разных языках программирования. Например, если надо поддерживать 2 платформы, то требуется увеличение трудозатрат и команды в 2 раза. Плюс в 2 раза больше бюджетов на поддержку и развитие. Можно добавить, что во многих компаниях уже скопилась большая база кода, который также хотелось бы унаследовать в новых решениях.
Вторым важным моментом является наличие необходимых компетенций (знаний и опыта) внутри команды – если их нет, то потребуется время на обучение.
Для того, чтобы решить обе этих проблемы, на рынке появились инструменты кроссплатформенной разработки, предлагающие:
— максимизировать общую базу кода на едином языке программирования, чтобы продукт было проще разрабатывать и поддерживать;
— использовать существующие компетенции и специалистов для реализации приложений на новых платформах.
Так как языков программирования (и сред) сейчас наплодилось очень много (и специалистов, владеющих этими языками), то и инструментов для кроссплатформенной разработки существует изрядное количество. В данной книге нас интересуют только инструменты для создания мобильных бизнес-приложений, поэтому в следующих главах мы подробнее разберем как они работают. А пока чуть детальнее каждый из плюсов кроссплатформенной разработки:
Общая база кода. В зависимости от выбранного инструмента разработчик сможет шарить между платформами: ресурсы приложения (картинки, шрифты и прочие файлы), логику работы с данными, бизнес-логику и описание интерфейса. И если с ресурсами и логикой (обработки данных и бизнес-) все довольно просто, то вот с интерфейсом следует быть осторожнее, так как для каждой из платформ есть свои рекомендации и требования.
Использование существующих компетенций и команды. Здесь стоит учитывать не только язык программирования, но и понимание механизмов работы операционных систем iOS/Android/Windows, а также набор дополнительных библиотек и инструментов разработки.
Итак, «нативные» инструменты предоставляются самими владельцами экосистем и позволяют получить максимум из возможностей целевой операционной системы, имеют полный доступ к родным API, оптимальную производительность и требуют отдельной команды разработки под каждую платформу.
Кроссплатформенные фреймворки позволяют сократить трудозатраты и ускорить выпуск приложений в том случае, если требуется поддержка нескольких платформ одновременно, и имеются (или развиваются) необходимые компетенции. В долгосрочной перспективе кроссплатформенные решения помогут сэкономить приличное количество человеко-часов, но для этого стоит учитывать особенности выбранного инструмента.
Архитектура iOS/Android и нативные API
Главный принцип, лежащий в основе кроссплатформенных решений — разделение кода на 2 части:
- кроссплатформенную, живущую в виртуальном окружении и имеющую ограниченный доступ к возможностям целевой платформы через специальный мост;
- нативную, которая обеспечивает инициализацию приложения, управление жизненным циклом ключевых объектов и имеющую полный доступ к системным API.
Для того, чтобы связывать между собой мир “нативный” и мир “кроссплатформенный”, необходимо использовать специальный мост (bridge). И как мы увидим в главе 3, именно bridge и определяет возможности и ограничения кроссплатформенных фреймворков.
Использование bridge всегда негативно сказывается на производительности за счет преобразования данных между “мирами”, а также конвертации вызовов API и библиотек. Сам по себе “кроссплатформенный” мир имеет сопоставимую с “нативным” производительность.
Итак, все кроссплатформенные приложения обязаны иметь нативную часть, иначе операционная система просто не сможет их запустить. А сами iOS, Android и Windows UWP предоставляют необходимые API для работы кроссплатформенных фреймворков:
- WebView используется в гибридных приложениях на базе PhoneGap или аналогов для запуска приложений и фактически выступает средой выполнения веб-приложений;
- JavaScript-движки используются в ReactNative и аналогах для быстрого выполнения JS-кода и обмена данными между Native и JS;
- OpenGL ES (или DirectX) используется в играх и приложениях на Qt/QML или аналогах для отрисовки интерфейса;
- UI-подсистема отвечает за нативный пользовательский интерфейс приложения, что актуально для ReactNative и Xamarin.
Более подробное описание данных подсистем в различных операционных системах вы можете найти в полной версии руководства по ссылке в конце статьи.
Архитектуры кроссплатформенных фреймворков
Все операционные системы имеют те или иные технические возможности по запуску кроссплатформенных приложений. Самое простое с технической точки зрения — использование WebView, которое есть у всех ОС (актуально для PhoneGap). Вторым вариантом является использование механизмов низкого уровня вроде OpenGL ES и языка C/C++ — это позволит разделять между проектами большинство логики (в играх или Qt), но будет ограниченно работать (или не работать) на Windows UWP. Если же вам будет нужен полностью нативный пользовательский интерфейс и нативная производительность с минимальными накладными расходами, то здесь начинают задействоваться системные API верхнего уровня — такой подход реализуется в Xamarin и ReactNative.
Чтобы лучше понять возможности и ограничения каждого из фреймворков, давайте рассмотрим, как архитектурно они устроены и какие из этого следуют возможности и ограничения.
PhoneGap
Решения на базе PhoneGap используют WebView и являются достаточно простыми с точки зрения реализации — создается небольшое нативное приложение, которое фактически просто отображает встроенный веб-браузер и single-page HTML. Нет никаких нативных контролов и прямого доступа к API — все интерфейсные элементы внутри веб-страницы просто стилизуются под родные. Для доступа к системной функциональности подключаются специальные плагины, которые добавляют JS-методы внутрь веб-браузера и связывают их с нативной реализацией на каждой платформе.
Как видим, PhoneGap позволяет разделять практически весь код между платформами, однако все еще требуется реализация нативной части на Objective C и Java (и C# для Windows). Вся жизнь приложения проходит внутри WebView, поэтому веб-разработчики почувствуют себя как рыба в воде. До тех пор, пока не возникнет потребность в платформенной функциональности — здесь уже будет необходимо хорошее понимание iOS и Android.
Также PhoneGap (он же Apache Cordova) используется в популярном фреймворке Ionic, который предоставляет большое количество готовых плагинов для системной функциональности.
Интерфейс приложений на основе WebView не является нативным, а только делается похожим на него с помощью HTML/CSS-стилей.
При разработке приложений на PhoneGap требуется опыт HTML, JavaScript, CSS, а также Objective C, Java и хорошие инженерные знания для интеграции нативной и кроссплатформенной частей. Пользовательский интерфейс организован по принципу одностраничного HTML — в реальных приложениях со сложным интерфейсом будут подергивания и подтормаживания (особенности мобильных WebView, которые еще и могут отличаться у разных производителей). Для передачи данных через мост их необходимо сериализовать/десериализовать в Json. В целом, мост используется редко, так как вся жизнь приложения проходит внутри WebView.
Для передачи сложных структур данных и классов между нативной частью и WebView их необходимо сериализовать/десериализовать в формате JSON.
Напоследок отметим, что PhoneGap уже достаточно зрелое решение с большим количеством готовых плагинов.
Итак, PhoneGap можно рекомендовать для быстрой разработки простых приложений (до 15 экранов) с небольшой пользовательской аудиторией (например, решение внутри компании) или прототипов.
ReactNative
Одним из интересных решений в области кроссплатформенной разработки мобильных приложений является ReactNative, созданный в Facebook. Этот фреймворк дает возможность использовать JavaScript для описания нативного интерфейса и логики работы приложений. Сам по себе JS-движок обеспечивает производительность, сопоставимую с нативной. Однако не стоит забывать, что и в архитектуре ReactNative присутствует мост, снижающий скорость работы с платформенной функциональностью и UI.
При создании приложений на ReactNative разработчику будет необходимо также реализовывать нативную часть на Objective C, Java или C#, которая инициализирует JS-движок и свой JS-код. Далее JS-приложение берет управление в свои руки и при помощи ReactNative начинает создавать нативные объекты и управлять ими из JavaScript. Стоит добавить, что архитектура ReactNative позволяет осуществлять обновление JS-кода без перезапуска приложения (hot reloading). Это допускает обновление кроссплатформенной части без необходимости перепубликации приложений в AppStore и Google Play. Также можно использовать библиотеки из Npm и большое количество сторонних плагинов.
Необходимо учитывать, что из-за ограничений iOS (нет возможности реализовать JIT) код JavaScript на лету интерпретируется, а не компилируется. В целом это не сильно сказывается на производительности в реальных приложениях, но помнить об этом стоит.
Для передачи сложных структур данных и классов между нативной частью и JS-движком их необходимо сериализовать/десериализовать в формате JSON.
При создании приложений на ReactNative требуется опыт JavaScript, а также хорошие знание iOS и Android. Интеграцию нативной и кроссплатформенной частей легко сделать по официальной документации. Пользовательский интерфейс является полностью нативным, но имеет ограничения и особенности при стилизации из JS-кода, к которым придется привыкнуть. Для передачи данных через мост их необходимо сериализовать/десериализовать в Json. Плюс мост используется для управления нативными объектами, что также может вести к падению производительности при неэффективном использовании (например, часто менять свойства нативных UI-объектов из JS-кода при анимациях в ручном режиме).
Также следует учитывать юность фреймворка — имеются узкие места или ошибки, о которых узнаешь только во время разработки. И практически всегда требуется реализация нативной части на Objective C и Java.
Итак, ReactNative можно рекомендовать для быстрой разработки приложений средней сложности (до 40 экранов), в команде должны быть не только опытные JS-разработчики, но и хорошие специалисты по iOS (ObjC/Swift) и Android (Java/Kotlin).
Полную версию руководства вы можете найти на 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.
UPD: Вторая часть здесь.