1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/CarGuo-GSYFlutterBook

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
Flutter-SQS.md 41 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
Отправлено 10.03.2025 00:06 5767d61

Привет всем, меня зовут Гуо Шу Юнь, автор книги "Практическое руководство по разработке приложений с использованием Flutter" и ответственный за открытое программное обеспечение серии проектов GSY на GitHub. В настоящее время моя открытая версия gsy_github_app_flutter имеет более 13 000 звёзд и занимает первое место в общем рейтинге Dart среди китайских проектов.

Изображение 1

Данные взяты из: https://github.com/GrowingGit/GitHub-Chinese-Top-Charts/blob/master/content/charts/overall/software/Dart.md

Прежде чем начать

С момента как Flutter был открыт, прошло уже почти семь лет. Я начал работать с Flutter в 2017 году, а сегодня, в 2022 году, можно сказать, что Flutter больше не является малочисленной платформой для кросс-разработки.

Как показано на следующей диаграмме, сейчас у Flutter более 135 000 звёзд, более 10 000 открытых и более 50 000 закрытых запросов на исправление ошибок, что свидетельствует о высокой активности сообщества и пользователей.

Изображение 2

По данным исследования, проведённого во второй половине прошлого года, Flutter занял первое место среди наиболее используемых и любимых кросс-платформ для разработки. Это заявление не означает, что вы обязательно должны учиться Flutter, но говорит о том, что независимо от того, нравится вам это или нет, Flutter уже доказал свою ценность.Изображение 3 image.png

Данные взяты из: https://rvtechnologies.com/10-reasons-why-flutter-is-growing-as-a-cross-platform-framework/

На самом деле, за последние два года я провёл некоторые простые исследования:

  • В 2020 году из 52 образцов 19 приложений использовали Flutter;
  • В 2021 году из 46 образцов 24 приложения использовали Flutter;

Эта выборка данных довольно мала, основана на моих личных предпочтениях и поэтому недостоверна и не представительна, но она может частично отражать текущее использование Flutter в Китае.

Данные взяты из: https://juejin.cn/post/7012382656578977806

Наконец, Flutter также поддерживает работу на веб-страницах и ПК, хотя я пока не внёс его в производственные процессы. Можно сделать вывод, что:

Веб

  • На данный момент Flutter Web поддерживает HtmlCanvas и CanvasKit(WASM). По умолчанию мобильные устройства используют HTML, а настольные — WASM;
  • На сайте pub.dev около 60% пакетов совместимы с вебом;
  • Размер и SEO являются самыми важными факторами, которые следует учесть заранее.

Дополнительные материалы: https://juejin.cn/post/7059619009213726733

Версия для персональных компьютеровНа данный момент версия для ПК менее развита по сравнению с Electron. Можно сказать, что версия Flutter для ПК может использовать меньше памяти и иметь меньший размер, а также лучше поддерживать FFI (Foreign Function Interface) для работы с C. Однако экосистема пока слабее, поддержка сторонних разработчиков ограничена, поэтому вам придётся решать больше вопросов самостоятельно.> Официальная версия для Windows уже выпущена

Дополнительные материалы: https://juejin.cn/post/7018450473292136456

Отличие Flutter от нативной разработки

Как кросс-платформенный фреймворк для создания графического интерфейса, Flutter имеет основное преимущество в том, чтобы обеспечить независимость UI от платформы при приемлемой производительности, то есть с точки зрения платформы, Flutter представляет собой "одностраничное" приложение.

1. Одностраничное приложение

Что такое "одностраничное" приложение?

Для нативных Android и iOS это значит, что вся кросс-платформенная UI по умолчанию работает внутри одного Activity / ViewController, по умолчанию существует только один Activity / ViewController. Таким образом, Flutter, React Native, Weex и Ionic по умолчанию работают таким образом, поэтому маршруты фреймворков обычно не связаны напрямую с маршрутами нативных приложений.

Например, рассмотрим следующий пример:

  • В текущем стеке маршрутов Flutter находятся страницы FlutterA и FlutterB;
  • Когда открывается новый Activity / ViewController, запускается нативная страница X, которая затем добавляется в стек маршрутов нативного уровня, тем самым скрывая FlutterActivity / FlutterViewController, то есть скрывая FlutterA и FlutterB;
  • Теперь, когда открываем новую страницу FlutterC в стеке маршрутов Flutter, она также будет скрыта за счет нативной страницы X.Иллюстрация

Поэтому можно заключить, что по умолчанию кросс-платформенные приложения являются одностраничными, и их стек маршрутов несовместим с маршрутом нативного уровня.

Конечно, слово "по умолчанию" используется дважды, так как действительно возможно создание пользовательских смешанных стеков маршрутов, таких как официальный FlutterEngineGroup, сторонние фреймворки flutter_boost, mix_stack, flutter_thrio и т.д., все они предназначены для решения задач смешанной разработки.

2. Логика рендера

После рассмотрения различий в части "одностраничной" архитектуры, давайте поговорим о различных подходах Flutter к рендерингу.

На уровне рендера Flutter значительно отличается от других кросс-платформенных фреймворков. Ниже приведена схема сравнения текущих популярных моделей рендера:

Сравнение моделей рендера

  • Для нативного Android используется нативный код, который проходит через Skia и затем до GPU для окончательного рендера. Нативная система Android уже включает в себя библиотеку Skia;

  • Для Flutter контроллеры Dart кода проходят через Skia и затем до GPU для окончательного рендера, где на Android используется системная версия Skia, а на iOS — версия, которая встроена в проект;- Для проектов типа ReactNative/Weex код выполняется внутри соответствующего движка JavaScript, после чего он преобразуется в нативные контроллеры и использует возможности рендера этих контроллеров; (ПС: В этом году официальная версия наконец выпустит переоформленную версию: Новый архитектурный обзор React Native 2022 года)- Для кросс-платформенных фреймворков типа Ionic используются преимущественно возможности рендера WebView.

На Android Skia может использовать либо OpenGL, либо Vulkan, в зависимости от ситуации, а на iOS если есть поддержка Metal, то она будет использоваться для ускоренного рендера.

Из вышеописанного можно сделать вывод:

ReactNative/Weex и подобные кросс-платформенные решения имеют значительную связь с нативными платформами:

  • Преимущество заключается в том, что использование нативных контроллеров требует меньших затрат на интеграцию;

  • Однако недостаток состоит в том, что рендеринг сильно зависит от возможностей нативных контроллеров, что увеличивает степень耦合,并增加了后期开发过程中的维护成本。

Например: в iOS хорошо отладленные стили при переходе на Android могут вызвать ошибки; эффективные стили на Android могут не поддерживаться на iOS; эффекты контролов на iOS могут отличаться от эффектов на Android, например, при выполнении операций pull-to-refresh и AppBar. Если добавить мелкие различия между версиями каждого системы, проблема становится еще более сложной.

Например, различия в эффектах тени на Android и iOS.

Flutter отличается тем, что использует прямое взаимодействие с Skia и GPU, обеспечивая платформо-независимость контролов на Android и iOS. Другими словами, большинство Widgets в Flutter являются независимыми от Android и iOS. Основной принцип работы нативной платформы заключается в предоставлении аналогичного объекта Surface, после чего отрисовка соответствующих компонентов осуществляется с помощью Flutter.> Обычно используется объект FlutterView как контейнер для отрисовки; на Android он может использовать внутренние реализации таких классов, как SurfaceView, TextureView или FlutterImageView; а на iOS — это UIView, использующий слои (layers) для отрисовки.Поэтому компоненты Flutter могут обеспечивать единый внешний вид на различных платформах, но смешивание их с нативными компонентами требует значительных усилий и затрат, что связано с возможностью использования нативных компонентов через механизм PlatformView. Реализация PlatformView сама по себе может вызывать проблемы с памятью и клавиатурой, поэтому её внедрение также является дорогостоящим процессом.

В последних версиях системы настоятельно рекомендовано использование Hybrid Composition, что делает его немного лучше по сравнению с ранними версиями PlatformView, хотя некоторые проблемы всё ещё остаются. Например, проблема смены клавиатуры при вводе пароля или мерцание экрана при переходе между страницами.

3. Проектная структура

Структура проекта

Как показано на приведённой выше 图为所示,默认情况下 Flutter 工程结构是这样的:

  • android 是原生项目的目录,可以在此处配置应用程序名(appName)、图标(logo)、启动画面以及 AndroidManifest.xml 等;
  • ios 是 iOS 项目的目录,在这里可以配置启动画面、图标、应用名称及 Info.plist 文件等;
  • build 目录是在编译过程中生成的,通常被 Git 忽略,打包过程及其输出结果均存放于此;
  • lib 目录用于编写 Dart 代码,主程序入口通常是 main.dart;
  • pubspec.yaml 文件是 Flutter 工程中非常重要的文件之一,无论是静态资源引用(例如图片、字体)、第三方库依赖还是 Dart 版本声明都会记录在此文件内。

如下图是对 pubspec.yaml 文件结构的说明


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

В последних версиях системы настоятельно рекомендовано использование Hybrid Composition, что делает его немного лучше по сравнению с ранними версиями PlatformView, хотя некоторые проблемы всё ещё остаются. Например, проблема смены клавиатуры при вводе пароля или мерцание экрана при переходе между страницами.

3. Проектная структура

Структура проекта

Как показано на приведённой выше иллюстрации, по умолчанию структура проекта Flutter выглядит следующим образом:

  • android — директория для native проекта, где можно задать имя приложения (appName), логотип (logo), splash screen и файл AndroidManifest.xml.
  • ios — директория для iOS проекта, где можно задать splash screen, логотип, название приложения и файл Info.plist.
  • build — директория, которая создаётся во время сборки, обычно игнорируется Git, здесь хранятся результаты сборки и её выходные данные.
  • lib — директория для написания кода на Dart, главный входной файл программы обычно называется main.dart.
  • pubspec.yaml — важнейший файл проекта Flutter, который содержит информацию о зависимостях библиотек, статических ресурсах (например, изображения, шрифты) и версии Dart.

Следующий рисунок демонстрирует структуру файла pubspec.yaml:pubspec.yaml структура

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

Далее представлен пример структуры Flutter плагина. Flutter делится на типы Package и Plugin,

  • Если это проект типа Package, то это чистый Flutter пакет, который не содержит никакого кода на нативном языке;
  • Если это проект типа Plugin, то это Flutter плагин, который включает код для платформ Android и iOS.

4. Упаковка и отладка

Перед запуском Flutter необходимо выполнить команду flutter pub get, чтобы синхронизировать и скачать сторонние зависимости. Сторонние зависимости обычно хранятся в директории (Mac) /Users/ваш_имя_пользователя/.pub-cache.

После успешной загрузки зависимостей можно запустить проект Flutter через команду flutter run или нажав кнопку "Run" в среде разработки (IDE). Этот процесс требует выполнения некоторых сетевых операций в нативных проектах, таких как:

  • Синхронизация Gradle и aar зависимостей на платформе Android;
  • Выполнение pod install для синхронизации зависимостей на платформе iOS;

Если требуется следить за прогрессом синхронизации:

  • На платформе Android выполните команду ./gradlew assembleDebug в директории android/;
  • На платформе iOS выполните команду pod install в директории ios/.Среди синхронизируемых плагинов, если это Plugin с логикой на native платформе, то в корневой директории проекта будут находиться файлы .flutter_plugins и .flutter-plugins-dependencies. Эти файлы игнорируются системой контроля версий (git) и используются для указания местоположения плагинов на локальной машине. При запуске Flutter эти пути используются для динамического добавления зависимостей.

По умолчанию Flutter работает в режиме JIT при запуске в debug, что делает его менее производительным, но позволяет использовать hot-reload.

В режиме release используется AOT компиляция, что значительно увеличивает скорость работы. Кроме того, Flutter по умолчанию использует CPU для запуска на эмуляторах и GPU для запуска на реальных устройствах, поэтому производительность также различается.

Внимание: на реальном устройстве iOS 14 запуск в режиме debug после отключения соединения невозможен повторить.

Если проект сталкивается с проблемами кэширования, можно очистить кэш, выполнив команду flutter clean.

И последнее, почему Flutter не поддерживает горячую загрузку?

Ранее было упомянуто, что ReactNative и Weex используют JavaScript для преобразования UI-компонентов в native компоненты, а значит, что сама часть кода на JavaScript является просто текстом. Отправка этого текста через code-push не нарушает требование платформы.

В случае Flutter, скомпилированные файлы являются двоичными, и отправка этих двоичных файлов явно противоречит требованиям платформы.> После сборки в режиме release Android генерирует два динамических библиотеки: libapp.so и libflutter.so; iOS создает два файла: App.framework и Flutter.framework. Поэтому сторонние решения для горячего обновления Flutter включают такие как: MXFlutter, Fair, Kraken, LiteApp, NEJFlutter, Flap (MTFlutter), flutter_code_push (Chimera) и так далее. Однако эти фреймворки не отправляют исполняемые двоичные файлы напрямую. На рынке можно выделить две основные категории решений для динамизации в зависимости от различий в DSL (Domain Specific Language): ориентированные на фронтенд и ориентированные на конечное устройство.На следующей схеме показаны примеры таких решений, как LiteApp компании WXG, MxFlutter компании Tencent и Kraken компании Alibaba (Бэйхай), которые ориентированы на фронтенд и используют JavaScript/TypeScript.

image11

Ссылка: https://mp.weixin.qq.com/s/OpgqjTIiB6z9YiN1FTDeYQ

На следующей схеме представлены примеры таких решений, как Flap и flutter_code_push, которые ориентированы на конечное устройство и требуют работы над DSL или кодом на Dart.

image12

Ссылка: https://tech.meituan.com/2020/06/23/meituan-flutter-flap.html

Наконец, относительно поддержки динамического обновления Flutter, можно обратиться к следующей таблице:

image13

Ссылка: Flutter реализует динамическое обновление — технический анализ

5. Простое описание Flutter

Здесь мы рассмотрим некоторые аспекты Flutter, связанные с Dart, особенно для нативной разработки следует прежде всего понять концепцию реактивного программирования и Widget.

Реактивное программирование

Реактивное программирование также известно как декларативное программирование, что является основой современной фронтенд-разработки. Это также тренд в области клиентской разработки, такой как Jetpack Compose и SwiftUI.

**Jetpack Compose и Flutter имеют очень похожие характеристики на поверхности.**Основная идея реактивного программирования заключается в том, чтобы не выполнять обновление интерфейса вручную, а просто "объявить" его через код, установить связи между данными и интерфейсом, и при обновлении данных интерфейс будет автоматически обновлен.

Из точки зрения кода, для нативной разработки нет необходимости использовать XML для создания макетов или storyboard. Макет полностью создается с помощью кода, то есть "что видишь, то и получаешь". Также нет необходимости работать с объектами интерфейса для присваивания значений или обновления; все, что требуется, это настройка отношений между данными и интерфейсом.

Основное отличие реактивного программирования от методов данных-биндинга или MVVM состоит в том, что каждый раз он заново строит и корректирует всю деревянную структуру отрисовки, а не просто выполняет операцию видимости для UI. Вот ниже приведён пример третьей стороны для адаптивного интерфейса в Flutter: responsive_framework.

Виджет

Widget — это базовый концепт в Flutter, с которым мы работаем напрямую при написании кода. **Внутри Flutter всё является виджетом, виджеты являются неизменяемыми (immutable), каждый виджет представляет состояние одной кадровой фреймы.**Поэтому Widget, как объект immutable, не может являться настоящим объектом пользовательского интерфейса. Настоящие объекты уровня View в Flutter — это Element и RenderObject. Абстракция Element — это часто используемый нами BuildContext.

Пример: в следующем коде Text виджет testUseAll используется трижды на одном экране, и код корректно отображается. Если бы это был настоящий View, он не смог бы использоваться одновременно несколькими местами на одном экране.

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

Интересный вопрос

Заключение: один интересный вопрос. Некоторые люди спрашивают, передаются ли значения или ссылки в Flutter? На этот вопрос есть множество путаницы в интернете, но ответ очень прост:

Все в Flutter — это объекты, даже такие примитивные типы данных, как int, double, bool, тоже являются объектами. Как вы думаете, что передаются при работе с объектами?

Однако операции над объектами могут различаться. Например, операции сложения, вычитания, умножения и деления для классов int и double вызывают методы операторов этих классов, а затем возвращают объект типа num.

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

Flutter и Compose

И последнее, поговорим немного о Flutter и Compose.

С момента появления Jetpack Compose вопрос выбора между Flutter и Compose начал возникать в Android-разработке, как это было ранее с iOS-разработчиками, выбирающими между Flutter и SwiftUI. Для Android-разработчиков этот выбор может быть "более болезненным", так как Flutter и Compose имеют общего "отца".

Здесь я предоставляю лишь своё личное понимание и не претендую на официальную точку зрения:

Цели будущего развития Flutter и Compose будут довольно схожими, но их первоначальные цели были различными.

Сначала, Compose является новой UI-библиотекой серии Jetpack, осознайте это! Compose — это часть серии Jetpack, поэтому его можно использовать для разработки пользовательского интерфейса Android, поэтому вы можете выбрать не использовать его, но вы всё равно сможете разрабатывать пользовательский интерфейс Android.Затем рассмотрим цель создания Compose: он был создан для того, чтобы переопределить способ написания пользовательских интерфейсов на Android, чтобы повысить эффективность разработки нативных пользовательских интерфейсов Android и сделать методы разработки пользовательских интерфейсов Android актуальными для современной эпохи.> Нравится вам это или нет, декларативное программирование пользовательских интерфейсов стало трендом сегодняшнего дня, что демонстрируют такие технологии, как React, SwiftUI и Flutter.

Что же касается Flutter, то его ключевой особенностью является возможность работы на нескольких платформах, поскольку Flutter сам по себе не имеет своей собственной платформы. Некоторые говорят, что Fuchsia станет домом для Flutter, но это уже другая история, ведь Fuchsia должна сначала стать жизнеспособной.

Flutter был создан как новый UI-фреймворк для работы на нескольких платформах, от нижних уровней до верхних — всё это представляет собой смелые и инновационные решения, а использование языка Dart само по себе является очень смелым решением. Даже на веб-платформе Flutter использует WASM-модель CanvasKit.

Поэтому "вольность" Flutter с самого начала вызывала вопросы, и даже сейчас есть те, кто её не одобряет, потому что она в какой-то степени экстремальна и не всегда удобна.

Кроме того, с точки зрения происхождения и поддержки:

  • Flutter родился в группе проекта Chrome и использовал язык Dart, поэтому Flutter не относится к проектам Android;
  • Compose родился в команде Android и использует язык Kotlin;

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

  • Compose станет будущим пользовательским интерфейсом Android, и хотя вы можете не знать его сейчас, если вы продолжите работать в Android, вы должны будете его знать. Поддержка многоплатформенного использования Compose также развивается, хотя это не поддерживается Google, а предоставляется Jetpack Compose для многоплатформенного использования.
  • Будущее Flutter заключается в многоплатформенной разработке, более стабильной и надёжной многоплатформенной UI-библиотекой. Если ваш путь развития не связан с работой на нескольких платформах или вы не являетесь разработчиком для нескольких платформ, то вам это может и не потребоваться.

Стоит отметить, что эти библиотеки всё ещё сосредоточены на создании UI, поэтому выбор зависит от ваших предпочтений. Конечно, возможно, что важнее всего будет требование вашего руководителя.

По поводу конфликта между Flutter и Compose:

Из точки зрения проекта, Flutter и Compose могут казаться конкурирующими, но с точки зрения пользователя они не конкурируют.

Потому что для разработчика неважно, начнёт ли он учиться Compose или Flutter первым — каждый из этих навыков поможет ему освоить другой. Умение использовать один из них автоматически увеличивает шансы на успешное использование другого примерно до 70%.С точки зрения будущего:

  • Если вы работаете с нативными приложениями и ещё не столкнулись с Flutter, лучше начните с Compose, это будет полезно для вашей карьеры Android-разработчика, а затем переход к Flutter будет легче.

  • Если вы уже используете или изучаете Flutter, продолжайте развиваться, не стоит прекращать обучение из-за страха перед Compose. Когда вы освоите Flutter, вы окажетесь недалеко от понимания Compose.

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

С практической точки зрения: в настоящее время Android и iOS под Flutter 2.0 становятся всё более стабильными, Web-версия достигла стабильной ветки, а MacOS/Linux/Windows находятся в стадии бета-тестирования и доступны для просмотра через стабильную версию. Поэтому если вам требуется многоплатформенная разработка, включая ПК, Flutter является лучшим выбором.

Выбор React Native тоже возможен, кстати, последняя версия React Native — OnClickListener, которая всё ещё не достигла версии 1.0...Конечно, многие будут интересоваться тем, есть ли какие-либо проблемы с этими фреймворками. Основная проблема всех фреймворков заключается в том, что они имеют свои сложности; даже сетевые факторы могут стать вашими болевыми точками. Вопрос в том, готовы ли вы принять эти трудности, поскольку работа за кулисами любой платформы всегда связана с "грязной" работой. Путь Flutter к многоплатформенной разработке был сложным, и достижение стабильности на Android и iOS уже было большим шагом.Наконец, следует отметить следующий момент:

Многоплатформенная разработка существует благодаря наличию соответствующих нативных платформ, многие проблемы нативных платформ требуют решения именно на этих платформах. Те, кто говорит о том, что Flutter или React Native доминируют и унифицируют все методы и платформы, должны понимать различия между этими методами и платформами и учиться больше для этого.

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/CarGuo-GSYFlutterBook.git
git@api.gitlife.ru:oschina-mirror/CarGuo-GSYFlutterBook.git
oschina-mirror
CarGuo-GSYFlutterBook
CarGuo-GSYFlutterBook
master