Какие приложения написаны на flutter
Давайте поговорим о кроссплатформенной мобильной разработке, ибо повод есть! Не так давно, а именно в декабре 2018 года, на мероприятии от Google нам завезли «еще один фреймворк» — Flutter. Сегодня мы посмотрим на Flutter с разных сторон: историю, архитектуру, преимущества, недостатки, а также сравним его с React Native.
История возникновения
В начале стоит рассказать о предпосылках и истории возникновения Flutter. Все началось еще в 2014 году. В погоне за скоростью, команда Google Chrome экспериментировала с рендерингом содержимого страниц. Целью эксперимента являлась проверка: можно ли ускорить рендеринг, если отказаться от традиционной модели лейаута, попутно избавившись от груза обратной совместимости, накопившейся за многие годы существования веба.
Основой для экспериментов стал движок Blink, а результатом — прирост производительности в 20 раз за счет следующих изменений:
- Простой набор ограничений, влияющих на положение элемента на экране (Box Model) — минимальная и максимальная ширина и высота.
- Вместо большого набора правил, который может быть применен к любому элементу, каждый компонент определяет свою простую лейаут-модель (центрирование, паддинг, колонка).
Малое количество правил позволяет существенно оптимизировать лейаут на уровне компонента. А простая модель ограничений, распространяющаяся от родителя вниз по дереву, позволила добиться линейной зависимости между количеством элементов в дереве и временем лейаута. Все происходит настолько быстро, что Flutter не разделяет «создание» и «модификацию» нод. Вместо этого, в случае изменений родительского виджета, он инвалидирует все поддерево.
Результат этого эксперимента был взят за основу при разработке Flutter.
Откуда взялся Dart
Изначально Flutter был смесью С++ (часть движка Blink) + JavaScript, который использовался как основной язык для написания кода. Но у разработчиков возникли проблемы с JS. Решили поискать другой язык ему на замену. Команда исследовала больше десятка языков и выбрала Dart как наиболее подходящий. Основными преимуществами Dart являются:
- АОТ-компиляция. В результате имеем АРМ или х86 код с высоким быстродействием на пользовательском устройстве.
- JIT-компиляция. Дает возможность запускать проект в виртуальной машине на эмуляторе и реализовать hot reload длительностью менее одной секунды с сохранением состояния приложения.
- Строгая система типов. Позволяет забыть о выборе между TS и Flow.
- Tree shaking compiler. При сборке приложения удаляет весь неиспользуемый код.
- Generational garbage collection. Быстрое выделение и очистка памяти.
Компоненты фреймворка
Flutter состоит из трех слоев: Embeder, Engine и Framework.
- Embeder. Платформозависимый код, отвечающий за взаимодействие и запуск на конечной платформе.
- Engine. Написан на С/С++ и включает в себя Dart как уровень абстракции для работы с CPU, Skia — 2D библиотеку для рисования и подсистему для рендеринга текста, одолженную у Android.
- Framework. Cамая большая часть, полностью написанная на Dart. Разделение на слои позволяет легко построить приложения любой сложности. Можно использовать готовые виджеты из Material-UI или реализовать специфические компоненты на основе базовых виджетов. Есть возможность гибко работать с анимацией и обработкой жестов. Таким образом, можно комбинировать быструю работу с высокоуровневыми виджетами с возможностью внесения/переопределения более глубоких слоев.
Архитектура
Особенностью архитектуры Flutter является то, что он сам рисует каждый пиксель, контролирует жесты и анимацию. Он не использует ОЕМ-виджеты, как это делает React Native. Вместо этого, команда Flutter создала два набора виджетов для основных мобильных платформ: Material для Android и Cupertino для iOS. Таким образом, они заново отрисовали все UI-компоненты с обеих мобильных платформ, полностью повторив их поведение. Непосредственно с мобильной платформой (геолокация, звук, bluetooth) взаимодействие происходит через Platform Channels.
Фокус на потребителе
В процессе создания Flutter, была проведена большая работа по выявлению основных болевых точек при разработке мобильных приложений. Команда Flutter консультировалась с коллегами по нативной и кроссплатформенной разработке и сосредоточилась на следующих проблемах:
Cross-platform look and feel. При разработке бывают случаи, когда приложение должно выглядеть одинаково на обеих платформах. Учитывая особенности платформ, иногда этого довольно сложно добиться.
Platform diversity. Разнообразие вендоров, которые делают устройства на платформе Android, бывает, сказывается неожиданным образом на том, как выглядит и работает мобильное приложение.
Две команды. При разработке отдельных приложений для iOS и Android, приходится содержать две команды, которые разрабатывают одни и те же функции. А также есть необходимость синхронизировать релизы при вводе в строй мажорных обновлений, чтобы пользователи одной из платформ не были ущемлены в функционале.
Polishing. При кроссплатформенной разработке, отдельным процессом стоит упомянуть полировку верстки, которая, например, на iOS выглядит хорошо, а на Android содержит изъяны. И наоборот.
Performance. Производительность итогового решения при кроссплатформенной разработке иногда оставляет желать лучшего. Те же Cordova и React Native могут доставить немало головной боли.
В итоге нам предлагают:
Fast development cycles. Обновление приложения с полным сохранением состояния в эмуляторе занимает меньше секунды (в большинстве случаев).
Up to 120 FPS. Разработчики заявляют о готовности платформы рендерить на скорости вплоть до 120 кадров в секунду.
Pixel perfect rendering. Flutter заведует всем на экране. Рендерингом каждого пикселя, анимацией, обработкой жестов. Это позволяет добиться максимального сходства в работе на разных платформах и минимизировать влияние платформы на итоговый внешний вид приложения.
Rich set of customizable widgets. Вместе с фреймворком поставляется готовый набор легко катализируемых виджетов, который покрывает все гайдлайны Material-UI и реализует набор специфических для iOS виджетов.
Supports iOS, Android, Web, Desktop. Фактически, архитектура позволяет Flutter работать на всем, у чего есть GPU и экран. Сейчас поддерживается iOS и Andorid. Web и desktop — в активной разработке.
One team. Одна команда и одна кодовая база позволит существенно сэкономить на разработке.
Несмотря на молодость фреймворка, он получил широкое распространение еще до релиза первой версии. Самыми скачиваемыми приложениями, использующими Flutter, являются:
- Xianyu — 50 000 000+ загрузок;
- GoogleAds — 5 000 000+ загрузок;
- Hamilton Musical app — 500 000+ загрузок;
- Reflectly — 100 000+ загрузок (приложение было полностью переписано с React Native на Flutter).
К релизу первой версии Flutter состоялся Flutter Live Event, на котором фреймворк представили широкой публике. Вместе с ним представили инструмент Flare для создания анимаций и CI/CD-систем от Codemagic специально для Flutter. Анонсирован широкий набор инструментов для разработчика и поддержка основных IDE:
- AndroidStudio;
- Intellij IDEA;
- VSCode.
В дополнение к этому, есть сайт, на котором перечислено огромное количество приложений, написанных на Flutter. Есть отдельная книга, которая распространяется бесплатно и описывает опыт и истории успеха разработки приложений с помощью Flutter.
Как уже упоминалось выше, Flutter сконцентрирован на решении проблем бизнеса (стоимость разработки) и разработчика (удобство и скорость). Для этого Google вложил огромные усилия в тулинг для разработки.
Widget inspector. Навигация по дереву виджетов. Щелчок по виджету отправит вас к тому месту, где он вызывается в коде.
Debug. Поддержка дебага из окна IDE. Достаточно поставить точку остановки и запустить приложение в debug-режиме.
Debug paint. Отрисовка отступов и маркеров позиционирования для быстрого понимания того, что влияет на положение элемента.
Repaint rainbow. Постоянно меняющаяся радуга вокруг элементов, которые перерисовываются. Это позволяет отследить нежелательную активность.
Performance window. Позволяет следить за скоростью отрисовки и количеством перерисовок отдельных компонентов. Если какой-то виджет будет слишком активным, спиннер слева от колонки окрасится в желтый или красный цвет.
Profiling. Используется для глубокой отладки работы приложения.
Сравнение с React Native
Сравнение с React Native я бы начал с github-репозиториев. Это первое, что видит разработчик на подходе к выбору технологии.
Статистика GitHub за июнь 2019 года
Из статистики видно, что Flutter молодой и динамично развивающийся фреймворк. По звездному рейтингу он вплотную приблизился к React Native, в то время как по количеству открытых issues, имеет десятикратное преимущество. 5К issues, а также тот факт, что количество новых issues превышает количество закрываемых, говорит о стремительном развитии как комьюнити, так и платформы. Ее активно тестируют и репортят баги. Сюда же стоит отнести и большое количество закрываемых ПР, что также говорит об активном комьюнити и поддержке.
Преимущества, которые обещает нам каждый из пары, я разделил на следующие основные категории:
Write once. Суть кроссплатформенных фреймворков в обещании «написал раз — запустил везде». В обоих случаях на 100% этого не достичь. Но за счет того, что Flutter самостоятельно контролирует отрисовку, жесты и анимации, проблем с подпиранием нюансов той или иной платформы будет всегда меньше. React Native, полагаясь на ОЕМ-виджеты, не всегда может обеспечить гладкий и беспроблемный внешний вид на обеих платформах.
Learn once. React Native, имея в своей основе ReactJS, выигрывает за счет большой популярности как самого языка JavaScript, так и React-фреймворка. Даже если свое знакомство с React вы начнете с React Native, для вас не составит большого труда перейти на web-разработку. И наоборот: имея в штате React-разработчиков, можно достаточно быстро начать работать с React Native. В случае с Flutter, есть большие перспективы с запуском на «любых платформах», но на данный момент он не может состязаться наравне.
Bundled components. В комплекте как с React Native, так и c Flutter, идет готовый набор компонентов (UI, анимация, верстка), но преимущество здесь все же за Flutter, так как каждый из существующих компонентов будет отрисован на обеих платформах. Возможно, некоторые будут смотреться чужеродно на сторонней платформе, но вопрос поиска и подбора компонентов на замену iOS-версиям виджетов в Android решается. Хорошим примером будет PickerIOS, аналогов которому по внешнему виду нет в Android. Приходится прибегать к помощи сторонних компонентов, например, ‘recat-native-wheel-picker-android’.
Performance. Итоговое приложение на Flutter будет представлять собой нативный код, который при прочих равных условиях будет всегда быстрее JavaScript.
Third party libs. React Native здесь вне конкуренции. NPM предоставляет нам множество библиотек на любой вкус. В то же время DartPub, ввиду молодости платформы, не обладает подобным богатством выбора. Множество библиотек, если и есть, все еще молоды.
World wide usage. Несмотря на то, что Flutter набирает популярность и имеет активно развивающееся комьюнити в мировом масштабе, он все еще не может обойти React Native по популярности (согласно Google Trends, исключение составляет США).
Developer experience. Сравнивая ощущения при разработке, Flutter нокаутирует React Native по качеству и количеству всевозможных инструментов для разработчика.
Debug and Profiling. Flutter имеет отдельный режим сборки приложения, который помогает в профилировании и отладке сложных кейсов. В то же время для React Native это более трудоемкий и сложный процесс.
Code push. На данный момент аналогов во Flutter не существует. Разработчики утверждают, что эта задача — решаема. Если для кого-то эта функция важна, есть issue на github, за которым можно следить.
В итоге, оба фреймворка по абсолютной сумме баллов идут практически наравне: 4,5 (React Native) против 5,5 (Flutter). Но каждый из вас может сделать свой вывод. Кому-то может быть жизненно необходим code-push, и ради этого он готов сражаться со средствами разработчика в React Native. Для кого-то хайповость, инструментарий и потенциал могут стать решающим фактором в выборе в пользу Flutter. Третьим — Dart станет непреодолимой преградой. А четвертым, наоборот, по душе Dart, который они в тайне от всех изучают уже год к ряду. На практике, на итоговое решение влияют не столько звездочки в репозитории и фишки фреймворка, сколько множество факторов окружающей среды конкретного проекта и бизнеса.
Сравнение архитектур
С архитектурной точки зрения, у этих фреймворков мало общего. Общим является платформа, на которой запускается приложение, и, в некотором смысле, способ взаимодействия с сервисами, предоставляемыми платформой. В остальном они принципиально разные.
Flutter работает напрямую с канвасом и событиями, сам отрисовывает виджеты, имеет собственную модель лейаута и рендера. React Native опирается полностью на OEM-виджеты, которые предоставляет платформа и имеет прослойку в виде движка Yoga, который реализует флексбокс лейаут на стороне платформы, а рендеринг уже полностью зависит от платформы.
Flutter компилируется в нативный код, а React Native выполняется внутри JavaScriptCore, что не самым лучшим образом влияет на скорость запуска и работы приложения. В React Native все взаимодействие с платформой происходит через бридж, который добавляет накладные расходы на сериализацию/десериализацию данных между средой исполнения JS и нативным кодом.
Во Flutter есть Platform Channels, которые работают сходным с бриджем образом, для реализации взаимодействия с сервисами платформы (сенсоры, камера и т.п.), но за счет нативного кода работают существенно быстрее. Стоит также упомянуть, что дни бриджа сочтены, так как React Native переходит на архитектуру с JavaScriptInterface, чтобы избавиться от оверхеда на бридже.
Последним отличием является язык, который используется для написания кода. В React Native — это JavaScript со всеми его плюсами и минусами, во Flutter — относительно молодой язык Dart, который в свое время был разработан с целью заменить JS.
«За» и «Против» использования Flutter
Хайп. Технология явно словила волну успеха, имеет активно развивающееся комьюнити и интересные архитектурные подходы в своей основе. Это, на мой взгляд, залог длительного и успешного существования фреймворка.
Быстрое написание кода. Собственный рендеринг, независимость от ОЕМ-виджетов и богатый инструментарий разработчика существенно ускоряет написание кода и поддержку двух платформ одновременно.
Один и тот же код запускается на двух и более платформах. На данный момент полноценно поддерживаются только iOS и Android. Web и desktop — в активной разработке. Но их выход в продакшн — вопрос ближайшего будущего.
Меньше тестирования. За счет pixel perfect rendering, тестирование и устранение платформо-зависимых багов и нюансов верстки будет проходить существенно быстрее.
Быстродействие. Компиляция в нативный код не оставляет сомнений в этом утверждении.
Одинаковый UI на всех устройствах. При необходимости написать приложение с уникальным дизайном, который должен быть одинаковым на двух мобильных платформах, Flutter становится незаменимым инструментом для кроссплатформенной разработки.
«Против»:
Зрелость. Молодость платформы — неизбежный спутник Flutter. В этом случае, React Native — более устоявшееся решение, под которое будет легче найти разработчиков.
Крутая кривая обучения. Dart добавляет накладные затраты на внедрение Flutter за счет необходимости изучать и вникать в новый язык.
Новые нативные UI компоненты. В случае с React Native, они могут быть подключены в проект достаточно быстро. Во Flutter все новые появляющиеся на стороне платформы элементы UI должны быть заново отрисованы.
Отсутствие вакансий на рынке. На данный момент их очень мало. Это должно измениться в будущем. Но сейчас это может стать препятствием для разработчика, который не хочет вкладывать свои силы в изучение новой технологии.
Опасения, что Flutter не способен закрыть потребности бизнеса. Обещая успешную работу на всем, у чего есть GPU и экран, может оказаться запускаемым везде, но не быть востребованным в бизнесе.
Итоги
На сегодня браузеры прочно обосновались на всех платформах и достаточно приемлемо отображают страницы любой сложности. Даже те, которые не были специально для них оптимизированы. То есть это не является чем-то недостижимым.
Я считаю, что успех Flutter остается вопросом времени, умноженном на усилия комьюнити и поддержке Google по написанию production-ready ембедеров для всех самых популярных платформ.
В нашем блоге Артем Зайцев и Евгений Сатуров из студии Surf, сертифицированного агентства Google, расскажут, почему и как так получилось:
Кроссплатформенные решения давно привлекают желающих быстро и незатратно запустить MVP-продукт одновременно под несколько платформ. Причина проста — единая кодовая база. Ее легче поддерживать: артефакты централизованы, нет дублирования логики и правок одних и тех же багов под каждую из платформ. Да и людей для ее поддержки и создания требуется меньше — нет необходимости содержать двух нативных разработчиков.
Существующие фреймворки либо сложны, либо не слишком производительны в силу нюансов технической реализации, либо полны багов. С их помощью люди стремятся быстро завести минимальную функциональность, а в итоге обрекают себя на переписывание проекта в долгосрочной перспективе.
Совсем скоро ожидается финальный релиз нового фреймворка для мобильной разработки от Google — Flutter, который стал самой запрашиваемой кроссплатформенной технологией на Stack Overflow. Подчеркну, что он предназначен именно для мобильных приложений и охватывает две платформы: Android и iOS. На данный момент представлена Release Preview 2 версия. Новые проекты на Flutter попадают в специальную подборку, цель которой — показать возможности фреймворка. Сейчас фреймворк активно пополняется компонентами и архитектурными надстройками благодаря сообществу разработчиков (например, реализация Redux).
Почему нужно поверить во Flutter?
Отличный тулинг для быстрой разработки
Вам не придётся вылезать из привычной Android Studio. При помощи плагина она отлично приспосабливается под разработку Flutter-приложений.
Hot Reload — киллер-фича, позволяющая моментально переносить все изменения из кода на запущенный эмулятор или подключенное устройство.
Простота и выразительность вёрстки
Если вы когда-либо разрабатывали приложения под Android, уверен, вёрстка — это не то, от чего вы получали удовольствие.
С Flutter всё иначе. Во-первых, никаких XML-файлов с вёрсткой — виджеты создаются и настраиваются прямо в коде (чем-то напоминает Anko Layouts). Вместо View используются Widget.
Так выглядит код Flutter-проекта. Поначалу огромное количество скобок пугает, но такие “деревья” довольно наглядны. Flutter пропагандирует композицию: из готовых виджетов можно составить новый, как из конструктора. Почти у любого компонента есть свойство child или children, которое принимает другой элемент или массив элементов соответственно. Все просто и понятно. Сделать красивый пользовательский интерфейс можно достаточно быстро.
Во-вторых, прямо со старта создатели платформы предлагают разработчикам каталог готовых виджетов. Он содержит два набора элементов, Material Components и Cupertino, которые выглядят нативно для каждой из платформ. Кроме того, доступны кроссплатформенные виджеты. Их внешний вид и поведение идентичны на iOS и на Android-устройствах.
Реактивный фреймворк
Flutter компилируется в нативный код под каждую из платформ. “Под капотом” он использует Skia в качестве графического движка.
Ключевой особенностью архитектуры системы является то, что все виджеты, а также компоненты, ответственные за отрисовку виджетов на канве, являются частью приложения, а не платформы. Именно отсутствие необходимости в переключении контекста и использования "мостов" даёт прирост производительности, который, способствует достижению заветного показателя в 60 FPS при отрисовке UI.
Вся мощь платформы по-прежнему в ваших руках
Зачем отказываться от тонны полезного кода, который целое десятилетие создается в сообществе мобильных разработчиков? Все библиотеки, доступные в нативных приложениях SDK и платформенные API могут быть использованы для Flutter-приложений.
Настройка окружения
Начать работу с Flutter очень просто.
При разработке официальная документация советует использовать Android Studio, IntelliJ или VSCode c соответствующими плагинами, но подойдет любой текстовый редактор.
Шаг первый
Шаг второй
Если все прошло гладко, можно приступать к созданию первого проекта. Если найдены ошибки, doctor подскажет как их решить.
Шаг третий
Для использования Flutter в Android Studio необходимо поставить два плагина: Flutter и Dart. Установить их можно стандартным образом, открыв настройки и выбрав нужные плагины в поиске.
Подробно о настройке окружения написано в официальной документации.
Первое что бросается в глаза при виде Flutter-приложений — непривычный код. В мире Android-разработки используется Java, а с недавнего времени и Kotlin.
Теперь в одном ряду с ними стоит Dart. Google позиционирует его как альтернативу JavaScript со строгой типизацией, высокой производительностью и гибкостью.
Синтаксис Dart прост в освоении, хотя и не так красив как у Kotlin. Возможно, это дело вкуса и привычки.
Создание проекта
Проект можно создать, выполнив в консоли команду flutter create name или используя IDE (в Android Studio → New Flutter Project).
Структура приложения
После создания проекта вы увидите следующую структуру. В корневой директории приложения есть четыре пакета — lib, ios, android и test.
Первая — директория фреймворка. Там располагаются все dart-файлы и основной код приложения. Несмотря на то, что Flutter компилируется в нативный код, для каждой из платформ приходится писать некоторые нативные взаимодействия. Кроме того, можно встроить Flutter в уже существующее приложение. Для нативного кода предусмотрены два пакета — ios/android, в которых есть возможность писать на привычном для конкретной платформы языке — Obj-C/Swift или Java/Kotlin. В пакете test найдете тесты.
В корневой директории есть файл конфигурации pubspec.yaml — там подключаются библиотеки и т.д. Если говорить об аналогии, то для Flutter’а это, как build.gradle (он тоже есть, но уже в нативной Android части).
Пакет lib можно разбивать на дополнительные пакеты — тут уже дело вкуса и желания использовать ту или иную архитектуру. К слову, для создания приложения на Flutter используются различные приемы, которые можно посмотреть здесь.
В вашем проекте сразу будет файл main.dart, содержащий код с примером. У приложения единая точка входа — метод main. Он отвечает за создание корневого виджета.
Everything is a Widget
Все, что вы видите (или не видите) на экране, все, с чем происходит взаимодействие и само приложение — виджеты. Любая сущность пользовательского интерфейса — виджет. Текстовое поле, отступ или детектор жестов — виджеты. Приложение построено из них, как конструктор.
Согласно официальному сайту, “каждый виджет является неизменяемым описанием части пользовательского интерфейса”.
Для примера построим приложение с таким экраном:
Здесь присутствуют следующие виджеты:
Часть из них реализована в фреймворке, часть необходимо составить самим из готовых деталей.
Виджеты бывают двух типов Stateless и Stateful . Первые статичны (например, текст), вторые поддерживают изменение состояния (например, экран).
Stateless
Примером такого виджета в приложении может быть MyApp. Это корень приложения. Внутри разместим все, что требуется для отрисовки с помощью метода build.
Любой статичный виджет — наследник класса StatelessWidget . Вам всего лишь необходимо переопределить метод build, а в нем собрать необходимый элемент. Flutter пропагандирует композицию. Для создания нового элемента не следует расширять уже существующий.
В примере данный виджет строится из MaterialApp (корень приложения, основанного на компонентах из MaterialDesign), внутри которого лежит Scaffold — это экран.
MyHomePage — тоже виджет, который отрисовывает тело экрана, исключая AppBar . В данном случае он имеет состояние. О нем поговорим ниже.
Построение интерфейса происходит через передачу конструктора класса в соответствующее поле с инициализацией аргументов. Dart поддерживает опциональные параметры методов, благодаря этому достигается гибкость в создании UI.
Замечание: слово new в Dart, начиная со второй версии, опционально.
Такой вот компоновкой виджетов можно получить статичный экран приложения. Причем фантазия разработчика неограничена вообще ничем.
Statefull
Виджеты с состоянием поддерживают перерисовку при изменении их состояния ( State ). Чтобы сделать такой виджет необходимо наследоваться от StatefullWidget и создать класс-наследник State<T> , который является состоянием виджета и отвечает за то, что пользователь увидит на экране смартфона.
Изменение состояния виджета происходит через вызов метода setState() <> . Внутри можно, например, задать другой цвет фона кнопки, и фреймворк сам определит минимально необходимую перерисовку UI.
В моем случае главная страница MyHomePage будет виджетом с состоянием. Оно хранит _name — имя, которое будет выводится в текстовом блоке, и флаг загрузки _isLoading (отвечает за то, как будет отрисован внутренний виджет LoadingButton ; пример управления состоянием через родителя).
У кнопки есть коллбек, action , куда подается метод _generateName() . Замечу, что в Dart нет модификаторов доступа, типа private и public . Но если необходимо сделать приватным что-либо внутри модуля, то наименование должно начинаться с префикса “_”.
Метод _generateName асинхронный. Он отвечает за загрузку имени, изменяет флаг isLoading и устанавливает значение name , что приводит к перерисовке кнопки и текста.
Для изменения состояния обязательно нужно вызвать setState() <> . Без этого вызова виджет просто не будет перерисован.
Реализация лоадера оказалась довольно простой. В момент перерисовки подставляется либо текст, либо индикатор в кнопку.
Реализация занимает всего несколько строк
Transform.scale нужен, чтобы уменьшить размер.
Асинхронное взаимодействие в Flutter, собственно как и в Dart, основано на async-await . Подробнее можно посмотреть здесь, здесь и здесь.
С чего начать?
Сегодня, когда новые материалы по Flutter выходят едва ли не ежедневно, нет никакого дефицита в хороших курсах, помогающих подружиться с данной технологией.
Хороший пример базового курса по Flutter — курс на Udacity. Уроки разбиты на две главы, вдумчивое прохождение каждой из которых займёт 3-4 часа.
Если же курсы не ваш вариант, начните погружение в технологию через изучение исходников уже существующих проектов. Репозиторий awesome-flutter содержит немало таких проектов, а еще может похвастаться очень щедрой подборкой готовых библиотек, решений, сэмплов и прочих материалов для изучения и вдохновения.
Заключение
По результатам более глубокого погружения в тему, от былого скептицизма у нас не осталось и следа. Flutter не похож на эксперимент, а скорее показывает направление, в котором в ближайшие годы будет двигаться весомая часть индустрии мобильной разработки. Несколько смелых концепций, лежащих в основе Flutter, привносят в разработку новые идеи и возможности. Быстрое, почти интуитивное создание пользовательского интерфейса делает прототипирование и UX-эксперименты простыми как никогда и доступными каждому. В какой сфере Flutter найдёт своё применение — покажет время.
Flutter — первая кроссплатформенная технология в технологическом стеке Surf. До этого студия в течение 7 лет разрабатывала исключительно нативные приложения.
Технологию Flutter создали инженеры компании Google. Они собрали позитивный и негативный опыт всех существующих кроссплатформенных решений и вывели рецепт идеальной кроссплатформы.
- Flutter позволяет сэкономить без потерь в качестве. Разработка одного Flutter-приложения, которое будет работать и на iOS, и на Android-устройствах, стоит на 30% дешевле, чем разработка двух нативных приложений с нуля.
- Приложения на Flutter написаны на единой кодовой базе: тестировать и отлаживать проще, вероятность ошибок меньше.
- Нет рассинхронизации платформенных команд — релизы выходят без задержки.
- Пользователи не заметят никакой разницы по сравнению с нативными приложениями.
В отличие от PhoneGap, Cordova, Ionic и других веб-фреймворков, Flutter не рендерит пользовательский интерфейс на WebView. За визуализацию приложения отвечает собственный графический движок и несколько пакетов кастомизируемых виджетов: это позволяет в небольшие сроки реализовать практически любой дизайн интерфейса.
Flutter-приложения пишутся на языке Dart: он компилируется в нативный код той платформы, для которой готовится сборка. Поэтому UI-элементы, анимации, переходы между экранами работают так же хорошо, как работали бы в нативном приложении.
Человеческий мозг воспринимает картинку идеально плавной, если интерфейс обновляется с частотой 60 кадров в секунду. React Native не всегда может обеспечить такую частоту. Для Flutter это не проблема — он «выдает» производительность до 120 кадров в секунду.
Kotlin Native позволяет унифицировать между платформами лишь код бизнес-логики. Flutter — не только бизнес-логику, но и UI. Это важно: у типичного фронт-энд приложения, в том числе мобильного, пользовательский интерфейс — достаточно трудоемкая в реализации часть.
Одна команда разработки, два приложения, в два раза меньше проблем, 30-процентная экономия средств.
Flutter имеет доступ ко всем фичам поддерживаемых платформ. Технологии платформенных каналов позволяют обращаться из Dart-кода напрямую к открытым интерфейсам платформы: камере, GPS, сенсорам, файловой системе устройства и т.д.
Flutter-индустрия развивается — это сказывается и на ситуации на рынке труда. Порог вхождения в технологию низкий: фреймворк относительно простой. Язык привычный: Dart — объектно-ориентированный язык, по синтаксису напоминает смесь Java и JS. Поэтому всё больше специалистов приходит во Flutter из смежных сфер: Android, iOS, web.
Команда Surf — пионеры Flutter в России. Мы активно участвуем в развитии сообщества: наши разработчики основали первый русскоязычный подкаст о Flutter, написали известный пост о Flutter на habrahabr, регулярно выпускают новые статьи о технологии, выступают на конференциях.
Мы убедились в преимуществах Flutter на собственном опыте: успешно запустили внутреннее приложение для сотрудников продовольственного ритейлера, внутрикорпоративное мобильное решение для сотрудников KFC, первый российский мобильный банк на Flutter — Росбанк, приложение для самой большой сети аптек Ригла.
В: Как выглядит сборка приложения изнутри? Что во что компилируется?
В дебажной сборке на всех платформах на устройство тянется Dart VM для выполнения чистого Dart-кода без его компиляции в нативную библиотеку. Если в приложении есть платформозависимый код для Android (Java, Kotlin) или iOS (Objective-C, Swift), в сборках будут и эти библиотечные модули.
В: Каков размер релизной сборки под обе платформы?
О: Один из наших небольших проектов под Android весит 8,5 Мб, а под iOS — около 30 Мб (с более тяжёлой графикой и Swift-кодом).
В: Можно ли во Flutter работать с <название любой библиотеки под Android или iOS>?
О: Да, можно. Но эти библиотеки будут доступны только под ту платформу, под которую были написаны изначально.
В: Можно ли во Flutter работать с пермишенами/пушами/файловой системой?
О: Да, без каких-либо ограничений на обеих платформах.
В: Как во Flutter обстоят дела с шифрованием?
О: Для шифрования/дешифрования есть вменяемый порт Bouncy Castle на Dart.
В: Почему все говорят, что во Flutter можно делать безумные анимации? В чём отличия от нативных SDK?
О: Во многом потому, что это по факту это сингл-активити приложение и любые анимации при переходах между экранами возможны — в отличие от стандартных мульти-активити Android-приложений. UI очень гибкий к любым трансформациям: благодаря удачной коробочной библиотеке, анимации поддаются любые характеристики виджетов. Ну и наконец, производительный графический движок позволяет отрисовывать любые анимации в 60 FPS. А на некоторых устройствах — до 120 FPS.
В: Flutter поддерживает адаптацию под планшеты?
О: Планшетная адаптация выполняется без проблем — сразу под все платформы.
В: Flutter позволяет писать приложения, работающие в офлайне?
О: Возможность работы в оффлайне — не проблема для Flutter-приложений. Строго говоря, этот вопрос вообще не лежит в плоскости фреймворка и реализуется на более низком уровне. Flutter без ограничений поддерживает работу и с базами данных, и с файловой системой: можно реализовать любой вариант кэширования, который будет отвечать требованиям бизнеса.
В: Существуют ли примеры успешных Flutter-приложений?
О: Клиент для Taobao — одно из самых больших Flutter-приложений, которое покоряет китайский рынок и имеет более 100 тысяч активных пользователей. Шоукейс-видео про этот проект
Сайт с тысячами Flutter-приложений разной степени известности и совершенно разные по функциональности. Можно поставить приложение на обе платформы прямо со странички и посмотреть на них в действии.
Вы в блоге Surf
Мы разрабатываем мобильные приложе- ния и помогаем в цифровизации крупного бизнеса.
Впервые я погрузился в мир разработки мобильных приложений около десяти лет назад. Я только что купил свой первый iPhone (3GS), и мне было любопытно сделать что-нибудь для этого чудесного маленького устройства (статья Георга фон дер Ховена публикуется в переводе – прим. ред.).
Приложение, которое я задумал – своего рода электронная книга на стероидах. Около 50 глав информации, которая должна помочь пользователям в чрезвычайных обстоятельствах. То есть основной задачей было обеспечить возможность быстрого и удобного поиска информации в стрессовой ситуации.Сначала я написал стандартное веб-приложение с использованием библиотеки jQTouch и завернул его в контейнер PhoneGap для iOS. После запуска мой проект очень быстро попал в список рекомендованных приложений Apple в медицинской категории. Кажется, мне удалось сделать что-то хорошее.
Спустя несколько лет я переписал его как нативное мобильное приложение на Swift, а потом решил расширять охват и портировать проект на Flutter . Сейчас я расскажу, что из этого получилось.
Flutter: Святой Грааль для кросс-платформенных приложений?
Когда я только принял решение наконец создать Android-версию проекта, встал логичный вопрос – как это сделать. Писать нативное приложение или использовать кросс-платформенные решения? Ionic c React'ом или Vue? Или, может быть, новый модный Flutter вокруг которого сейчас много хайпа?
После небольшого исследования у меня сложилось впечатление, что в целом Flutter уже достаточно созрел, чтобы стать серьезной альтернативой для разработки. Люди, кажется, были им довольны, поэтому я решил попробовать.Поразительно, но сначала все шло очень хорошо. Я ничего не знал о Dart или принципах проектирования пользовательского интерфейса Flutter (пришедших из iOS Swift и XCode Interface Designer), но почти за одну неделю смог запустить проект на Android и iOS.
Когда дело дошло до тестирования, я столкнулся с очень странным поведением. Во время загрузки главы электронной книги отображается спиннер. Как только данные загружены и визуализированы, я заменяю спиннер на WebView. Это очень просто, и в 99% случаев все было нормально. Но иногда все зависало на спиннере. Очевидно, это не то поведение, которое вы ожидаете от приложения для чрезвычайных ситуаций.
После нескольких тестов и рефакторинга это решение казалось вполне жизнеспособным. До тех пор, пока некоторые ссылки в книге не стали ломаться на физическом устройстве iOS. При этом на Android и в эмуляторе iOS все работало нормально. Оказывается, я нашел еще один баг – в этот раз в пакете Flutter WebView. Я отправил отчет, который быстро был подтвержден. Однако обе ошибки все еще не исправлены (по состоянию на февраль 2021 года).
К этому моменту я потратил на поиск и описание ошибок примерно столько же времени, сколько на изучение Dart и портирование приложения в целом.Ад зависимостей
Я был крайне удивлен, что эти модули получают так мало любви и внимания от разработчиков Flutter. Вероятно, нынешняя команда Google недостаточно велика, чтобы поддерживать и развивать этот проект (8200+ незакрытых ишьюс на Github), либо их приоритеты больше его не включают.
Учитывая эти соображения, давайте взглянем на зависимости моего приложения Flutter и нативной версии проекта на Swift.
Нативное iOS приложение (Swift)
- AEXML – для анализа XHTML-файлов. Собственный iOS SDK не предоставляет DOM-парсер.
- FontAwesome.swift – позволяет использовать иконки FontAwesome.
Версия на Flutter
Ничего себе! Для чего мне нужно так много пакетов?
Так как мой проект – это не просто электронная книга, я добавил в него некоторые дополнительные фичи и сервисы, например:
- онлайн-поиск с использованием стороннего API;
- отображение информации о текущем местоположении пользователя с использованием геолокации и обратного геокодирования для помощи аварийным службам;
- быстрый набор экстренных номеров.
Для каждой фичи требуется взаимодействие с нативным SDK платформы: геолокацией, геокодированием или выполнением вызовов. Также требуется предотвращать уход в спящий режим, запрашивать у пользователя оценку, открывать карту, делиться контентом и делать другие вещи, которые делают все приличные приложения.
И iOS, и Android предоставляют эти функции из коробки для нативных приложений, но кросс-платформенные решения должны предоставлять плагины для каждой из них. А в случае Flutter каждый из них нужно реализовать на трех языках: Dart, Swift/Objective-C и Java/Kotlin.Таким образом, ваше приложение Flutter зависит от бесчисленных внешних библиотек, которые обеспечивают функциональность нативных приложений. И вы не знаете, кто и как их разрабатывает, какие у них планы, ограничения и мотивация. Каждая из них увеличивает технический долг вашего приложения.
Кроссплатформенность добавляет сложности
Если вы хотите свести технический долг к минимуму, придется написать 100% кода вашего приложения самостоятельно и использовать только нативные SDK для доступа к возможностям устройства. Конечно это практически невозможно. Поэтому, по крайней мере, тщательно выбирайте сторонние библиотеки, которые вы добавляете к вашему техническому долгу.
Когда я начал тестировать свое нативное приложение для iOS, то обнаружил огромную утечку памяти. Откуда она взялась? Разобравшись в концепции фантастических циклов сохранения, я наконец обнаружил виновника – стороннюю XML-библиотеку с ее бесконечной рекурсией.Если сторонняя библиотека написала на знакомом вам языке, вы вполне можете жить с этим долгом. Но каждое кросс-платформенное решение добавляет вашему приложению несколько уровней сложности и точек возможного сбоя.
В каждом пакете Flutter может встретиться баг в коде Dart, или в коде Swift/Objective-C, или в коде Java/Kotlin. А то и в нескольких частях сразу. Его может сломать любое обновление Flutter, Dart, iOS или Android – а вместе с ним сломается и ваше приложение на одной или всех платформах. Если вы не владеет всеми тремя языками и всеми поддерживаемыми платформами, то, вероятно, не захотите искать и устранять проблемы самостоятельно.
На кого вы хотите положиться?
Дополнительная сложность, которую привносит в проект Flutter, не была бы столь ощутимой и серьезной, если бы за ним стояла сильная организация, которая чувствует ответственность за обеспечение стабильной работы и взаимодействия Dart с нативными функциями SDK.
Большая часть этой важной функциональности исключена из основного проекта Flutter и оставления на усмотрение добровольцев из сообщества. Их мотивация и качество работы может очень сильно варьироваться. Если разработчики пакета, на который вы полагаетесь, забросят его, вам придется заплатить свой долг.Все, что вам реально нужно от Flutter, – это написать свое приложение на Dart и развернуть его на iOS и Android. И вы верите, что кросс-платформенное решение позволит вам это сделать, сэкономив время и деньги по сравнению с альтернативными решениями.
Теоретически Flutter может это сделать, но лишь теоретически. Его способность выполнять заявленные обещания все еще оставляет желать лучшего, особенно на iOS. Может быть это связано с уклоном в сторону Android или создателям продукта просто не хватает опыта, но как кросс-платформенная среда разработки Flutter пока проваливается. Если кросс-платформенное решение не может надежно обеспечивать работу с часто используемыми функциями на всех поддерживаемых платформах, оно теряет свои преимущества и лояльность разработчиков.
Я не уверен, что Google сможет сделать Flutter таким же удобным, как нативная разработка. Если они действительно стремятся к этому, то придется вложить больше усилий и денег в проект.
Может быть мне просто не повезло, и моими основными зависимостями оказались единственные два неисправных пакета из экосистемы Flutter. Читая открытые ишьюс на GitHub, я почему-то в этом сомневаюсь. Глядя на накопленный моим приложением с Flutter технический долг , я желаю удачи своим коллегам-разработчикам, которые уже запрыгнули в этот поезд.
Читайте также: