Повышение производительности, новые фичи Firebase, состояние десктопной версии, новые инструменты и многое другое.
Я — Евгений Сатуров, Head of Flutter в Surf и ведущий Flutter Dev Podcast. Представляю перевод официальной статьи про свежий релиз Flutter 2.8, дополненный моими комментариями.
Вот в северное полушарие и пришла та самая пора: листва опадает, на улице холодает, и последний стабильный релиз этого года уже тут как тут. Всем привет и добро пожаловать во Flutter 2.8! Этот релиз стал результатом труда 207 контрибьюторов и 178 рецензентов, которым удалось смёрджить 2 424 PR и решить 2976 проблемных моментов.
Благодаря коллективной работе контрибьюторов:
Мы ослабили влияние Flutter на политику сборки мусора Dart VM: это помогло избежать несвоевременного запуска циклов сбора при запуске приложения. К примеру, теперь перед рендерингом первого кадра на Android Flutter уведомляет Dart VM только о сигналах нехватки памяти уровня TRIM_LEVEL_RUNNING_CRITICAL и выше. При локальном тестировании это изменение в некоторых случаях сократило время отрисовки первого кадра на слабых устройствах на целых 300 мс.
В предыдущих релизах мы подходили к разработке с чрезмерной осторожностью, поэтому Flutter блокировал поток платформы при создании платформенных view. Благодаря рациональным аргументам разработчиков и результатам тестирования, мы выяснили, что в некоторых случаях сериализации можно избежать. Это сокращает задержку запуска Google Pay на слабом устройстве более чем на 100 мс.
Раньше запуск дефолтного менеджера шрифтов вызывал искусственную задержку при запуске первого Dart-изолята. Мы сократили задержку: отложили запуск дефолтного менеджера шрифтов, чтобы он происходил одновременно с запуском Isolate в Dart.
Для Android в релизе 2.8 мы выделили сервисному изоляту Dart VM свой собственный bundle, который можно загружать отдельно. Благодаря этому в приложении удаётся сэкономить до 40 мб памяти — пока не потребуется использовать сервисный изолят.
Кроме того, мы сократили объём требуемой памяти на 10%: научили Dart VM сообщать ОС, что страницы памяти, используемые AOT-программой, содержат сохранённую в файл информацию. Она, скорее всего, больше не будет считываться в память. В результате страницы, которые были заняты копией данных, можно очистить и переиспользовать.
В стабильном релизе 2.8 события трассировки отправляются в регистратор системной трассировки Android, если его активировали при запуске приложения. Более того, события отправляются, даже если это релизная сборка Flutter-приложения.
События трассировки во Flutter теперь отображаются (снизу) в инструментах регистрации системной трассировки для Android
Если активировать любую из фич трассировки на картинке, на временной шкале будут отображаться новые события для собранных виджетов, а также скомпонованных и отрисованных объектов, если такие есть.
В этом релизе DevTools добавились новые возможности профилирования производительности при запуске приложения. Новая статистика содержит анализ нагрузки ЦП: начиная с инициализации Dart VM и заканчивая рендерингом первого кадра на Flutter. Как только вы нажмёте кнопку «Profile app start up» («Профилировать запуск приложения») и статистика по запуску приложения загрузится, программа выберет для неё тег «AppStartUp» («Запуск приложения»). Профилирование загрузки приложения также можно запустить, выбрав сам тег (если он есть) из списка доступных пользовательских тегов. Так вы получите доступ к данным профилирования при запуске приложения.
С помощью платформенных view можно размещать в приложении компоненты нативного UI из платформы используемого вами устройства. Flutter web позволяет поместить HTML элементы в веб-приложение на Flutter с помощью виджета HtmlElementView. Если вы пользуетесь веб-версиями плагина google_maps_flutter, плагина video_player или следуете рекомендациям команды Flutter об оптимизации отображения картинок в веб, вы пользуетесь платформенными view.
Чтобы встроить платформенные view, в прошлых версиях Flutter приходилось создавать новый холст каждый раз. Чем больше платформенных view, тем больше холстов. Каждый новый холст требует очень много ресурсов, так как занимает всё окно целиком. В этом релизе Flutter переиспользует холсты, созданные для предыдущих view. В результате, вместо того, чтобы тратить в 60 раз больше ресурсов каждую секунду, приложение требует их один раз за время работы. Можно добавлять в веб-приложение несколько экземпляров HtmlElementView: это не снизит производительность и уменьшит лаги при скроллинге страницы с платформенными view.
[IMG alt="Баннерная реклама | Полноэкранная реклама | Видеореклама с вознаграждением | Нативная реклама | Реклама при запуске приложения
Google Mobile Ads SDK для Flutter"]https://habrastorage.org/r/w1560/ge...0d3ba00ed1e62c0c2ffc7774fb.png[/IMG]Баннерная реклама | Полноэкранная реклама | Видеореклама с вознаграждением | Нативная реклама | Реклама при запуске приложения Google Mobile Ads SDK для Flutter
Релиз поддерживает пять форматов рекламы, интеграцию с AdMob и Ad Manager и включает бета-версию новой фичи для размещения рекламы от посредников. С её помощью можно оптимизировать производительность приложения. Более подробно об интеграции Google Рекламы во Flutter-приложение и других способах монетизации рассказываем на новой страничке о монетизации на flutter.dev.
В предыдущих версиях webview_flutter режим гибридной компоновки («Hybrid Composition») уже был доступен, но не по умолчанию. Гибридная компоновка решает ряд проблем, существовавших в предыдущем дефолтном режиме «Virtual Display». Учитывая отзывы пользователей и статистику багов, мы решили, что пришло время сделать гибридную компоновку дефолтной. Кроме того, с webview_flutter добавилось несколько фич, о которых многие просили:
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:webview_flutter_web/webview_flutter_web.dart';
void main() {
runApp(const MaterialApp(home: HomePage()));
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
void initState() {
super.initState();
// required while web support is in preview
if (kIsWeb) WebView.platform = WebWebViewPlatform();
}
@override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(title: const Text('Flutter WebView example')),
body: const WebView(initialUrl: 'https://flutter.dev'),
);
}
При запуске в веб работает так, как и ожидается:
Следует заметить, что у текущей реализации webview_flutter для веб есть ряд ограничений. Она написана с помощью iframe: он поддерживает только загрузку простых URL и не умеет контролировать или взаимодействовать с загруженным контентом (подробнее читайте в the webview_flutter_web README). Однако по просьбе сообщества мы предоставляем доступ к webview_flutter_web в виде неофициального плагина. Если хотите его попробовать, добавьте следующую строку к pubspec.yaml:
dependencies:
webview_flutter: ^3.0.0
webview_flutter_web: ^0.1.0 # add unendorsed plugin explicitly
Если у вас возникла проблема с webview_flutter v3.0, пишите во Flutter репозиторий с пометкой «webview issue». Если же вы ещё не пользовались webview, прочтите новый codelab по webview, в котором пошагово расписан процесс внедрения веб-контента в приложении на Flutter.
flutter:
plugin:
platforms:
android:
package: com.example.hello
pluginClass: HelloPlugin
ios:
pluginClass: HelloPlugin
Однако Dart FFI не стоит на месте: сейчас можно внедрить платформо-специфичную функциональность с помощью кода, на 100% состоящего из Dart, как сделали с пакетом path_provider_windows. Даже если пакет не имеет нативных классов, вы всё ещё можете указать, что он поддерживает определённую платформу. В таком случае используйте свойство dartPluginClass:
flutter:
plugin:
implements: hello
platforms:
windows:
dartPluginClass: HelloPluginWindows
С помощью этих свойств вы можете указать, что пакет поддерживает только определённые платформы, даже если в приложении вообще нет нативного кода. Также вам необходимо указать класс Dart плагина. Подробнее об этом можно прочитать в документах о платформенных реализациях на чистом Dart на flutter.dev.
Плагины, которые перешли в стабильный канал для Android, iOS и веб, включают:
Realtime Database, Analytics и Remote Config теперь — полноценные плагины, готовые к использованию в продакшене.
import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart'; // generated via `flutterfire` CLI
Future<void> main() async {
// initialize firebase across all supported platforms
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
runApp(MyApp());
}
Программный код инициализирует приложение Firebase способом, соответствующим определённой поддерживаемой платформе, согласно информации в файле firebase_options.dart:
static const FirebaseOptions web = FirebaseOptions(
apiKey: 'AIzaSyCZFKryCEiKhD0JMPeq_weJguspf09h7Cg',
appId: '1:111079797892:web:b9195888086158195ffed1',
messagingSenderId: '111079797892',
projectId: 'flutterfire-fun',
authDomain: 'flutterfire-fun.firebaseapp.com',
storageBucket: 'flutterfire-fun.appspot.com',
measurementId: 'G-K029Y6KJDX',
);
Этот инструмент отправляется в данные в платформо-специфичных вложенных папках и ищет уникальный bundle ID. Затем использует его, чтобы найти подробную информацию по определённому проекту Firebase для соответствующего платформо-специфичного приложения или даже создать новый проект Firebase и новые платформо-специфичные приложения, если таких нет.
Какая в этом польза? Больше не надо скачивать и добавлять json-файл в Android-проект, скачивать и добавлять plist файл в iOS и macOS проекты или копипастить код в index.html web-проекта. Не важно, какую из поддерживаемых Firebase платформ вы выбрали, — этот кусочек кода на Dart инициализирует Firebase для приложения.
Однако, возможно, это не единственная инициализация, которую надо будет выполнить, чтобы FlutterFire-приложение заработало. Например, может потребоваться интегрировать символы Crashlytics в Android или iOS сборку. Однако с любым новым Firebase-проектом на это должны уйти считанные минуты.
В этом примере показано небольшое приложение-чат, которое использует Flutter, Firebase и DartPad. Их уже можно использовать, не устанавливая. Поддержка Firebase в DartPad уже включает основные API, аутентификацию и Firestore. Со временем в DartPad будут появляться новые сервисы Firebase.
Помимо этого, поддержка FlutterFire в DartPad даёт возможность использовать версию DartPad, встроенную прямо в документы.
В этом примере — документы для Cloud Firestore, в одном из которых написан код для примера приложения. Его можно запускать и редактировать прямо в браузере. Здесь можно создавать тестовый проект или даже копипастить код. Всё необходимое будет под рукой.
Firebase Authentication позволяет создавать новый аккаунт в два счёта, подтверждать адрес электронной почты, менять пароль, а в некоторых случаях — выполнить двухэтапную верификацию через SMS, залогиниться через номер телефона или даже объединить несколько пользовательских аккаунтов в один.
Пакет flutterfire_ui умеет воплощать основные сценарии аутентификации с минимальным количеством кода. Представим, что в проекте Firebase доступна аутентификация через email и Google-аккаунт:
С этим пакетом можно создать процесс аутентификации следующим образом:
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutterfire_ui/auth.dart';
import 'firebase_options.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) => MaterialApp(
home: AuthenticationGate(),
);
}
class AuthenticationGate extends StatelessWidget {
const AuthenticationGate({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) => StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
// User is not signed in - show a sign-in screen
if (!snapshot.hasData) {
return SignInScreen(
providerConfigs: [
EmailProviderConfiguration(),
GoogleProviderConfiguration(
clientId: 'xxxx-xxxx.apps.googleusercontent.com',
),
],
);
}
return HomePage(); // show your app’s home page after login
},
);
}
Этот код инициализирует Firebase. Если он заметит, что пользователь ещё не залогинился, покажет экран регистрации. В виджете SigninScreen есть возможность аутентификации через email и Google-аккаунт. Кроме того, код анализирует аутентификационное состояние пользователя с помощью пакета firebase_auth: как только пользователь зарегистрируется, вы сможете показать ему все остальные экраны приложения. С помощью этого кода вы получаете рабочий процесс авторизации для всех платформ, поддерживаемых Firebase: Android, iOS, веб и macOS.
Выполнив ещё несколько действий, вы с лёгкостью можете вставить изображение и какой-нибудь кастомный текст (подробнее в документации) и таким образом выстроить полноценный процесс входа в приложение:
Мобильная версия
Экраны flutterfire_ui адаптивны. Отображение на десктопном устройстве
Если у пользователей уже есть email и пароль, они могут их ввести и войти в приложение. Если они используют авторизацию через Google, приложение покажет им классический процесс авторизации через Google-аккаунт, независимо от того, мобильная это версия, веб- или десктопная. Если у них ещё нет аккаунта, они могут нажать на кнопку на экране входа в приложение и перейти на экран регистрации.
После входа в приложение или регистрации, приложение может показать пользователю экраны валидации электронной почты, смены забытого пароля, выхода из аккаунта и привязки аккаунта социальной сети для последующей аутентификации. Вход через email работает на всех платформах. Также есть возможность авторизации через аккаунты Google, Facebook и Twitter. Она частично поддерживается для Apple, но не работает на Android. Аутентификация с flutterfire_ui поддерживает несколько сценариев и схем навигации. Помимо этого, у flutterfire_ui есть возможность кастомизации и локализации. Подробная информацию и примеры — в документации на firebase.flutter.dev.
Аутентификация — не единственная связанная с Firebase UI фича, которую поддерживает flutterfire_ui. Чтобы в реальном времени показать пользователю список данных из запроса Firebase с возможностью бесконечной прокрутки, мы включили в этот релиз FirestoreListView, который можно добавить в приложение с активным запросом следующим образом:
class UserListView extends StatelessWidget {
UserListView({Key? key}) : super(key: key);
// live Firestore query
final usersCollection = FirebaseFirestore.instance.collection('users');
@override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(title: const Text('Contacts')),
body: FirestoreListView<Map>(
query: usersCollection,
pageSize: 15,
primary: true,
padding: const EdgeInsets.all(8),
itemBuilder: (context, snapshot) {
final user = snapshot.data();
return Column(
children: [
Row(
children: [
CircleAvatar(
child: Text((user['firstName'] ?? 'Unknown')[0]),
),
const SizedBox(width: 8),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Text(
'${user['firstName'] ?? 'unknown'} '
'${user['lastName'] ?? 'unknown'}',
style: Theme.of(context).textTheme.subtitle1,
),
Text(
user['number'] ?? 'unknown',
style: Theme.of(context).textTheme.caption,
),
],
),
],
),
const Divider(),
],
);
},
),
);
}
Так список выглядит в приложении:
А если вы хотите, чтобы пользователи могли создавать, читать, обновлять и удалять элементы таблицы, в FirestoreDataTable уже появляются такие возможности:
class FirestoreTableStory extends StatelessWidget {
FirestoreTableStory({Key? key}) : super(key: key);
// live Firestore query
final usersCollection = FirebaseFirestore.instance.collection('users');
@override
Widget build(BuildContext context) {
return FirestoreDataTable(
query: usersCollection,
columnLabels: const {
'firstName': Text('First name'),
'lastName': Text('Last name'),
'prefix': Text('Prefix'),
'userName': Text('User name'),
'email': Text('Email'),
'number': Text('Phone number'),
'streetName': Text('Street name'),
'city': Text('City'),
'zipCode': Text('Zip code'),
'country': Text('Country'),
},
);
}
}
Вот как это работает:
Подробнее об аутентификации, list view и таблицах данных — в документации по flutterfire_ui. Это предварительный релиз, и мы добавим в него новые фичи. Если у вас есть вопрос или вы знаете, какую фичу нужно добавить, перейдите в репозиторий на GitHub и сообщить о баге или задать вопросы в разделе обсуждений.
@JsonSerializable()
class Person {
Person({required this.name, required this.age});
final String name;
final int age;
}
@Collection<Person>(‘/persons’)
final personsRef = PersonCollectionReference();
С помощью данных типов можно делать запросы типобезопасным способом:
personsRef.whereName(isEqualTo: 'Bob');
personsRef.whereAge(isGreaterThan: 42);
Помимо этого, ODM поддерживает возможность описания строго типизированных подколлекций. С его помощью можно оптимизировать пересборку виджетов, используя фичу select. Об этом и многом другом — в документации к Firestore ODM.
Будем рады вашим отзывам. Чтобы оставить отзыв или задать вопрос, присоединяйтесь к треду о Firestore ODM в обсуждении FlutterFire.
Мы считаем, что для Flutter недостаточно работать на десктопных устройствах в стабильном канале (что уже возможно в бета-версии, если открыть доступ фиче-флагом). Он должен подходить для разных языков и культур мира, а также для людей с разными возможностями. Пока что мы не добились нужного результата, но идём к цели!
Мы не прекращаем работать над стабильной десктопной версией. Например, чтобы добиться синхронного отклика, мы полностью пересмотрели архитектуру взаимодействия Flutter с событиями, которые он получает от клавиатуры. Благодаря этому виджет теперь может распознавать нажатие на клавишу и останавливать прохождение сигнала дальше по дереву.
Благодаря работе, проделанной во Flutter 2.5 и Flutter 2.8, мы пофиксили баги и регрессионные ошибки. Продолжаем реорганизовывать обработку данных с клавиатуры на различных устройствах и рефакторить процесс форматирования текста во Flutter: это необходимо для десктопных приложений, где информация в основном вводится с помощью клавиатуры.
Кроме того, продолжаем расширять поддержку visualDensity во Flutter и применяем выравнивание к диалогам, чтобы сделать UI удобнее для десктопных устройств.
Команда Flutter — не единственная, кто работает над десктопной версией Flutter. Команда разработчиков для десктопов в Canonical в сотрудничестве с Invertase занимается реализацией наиболее популярных плагинов Firebase для Flutter на Linux и Windows. И это только один из примеров.
Подробнее о предварительном релизе — в блоге Invertase.
Чтобы посмотреть, какие пакеты мы планируем добавить в DartPad в будущем, переходите на статью в Dart wiki.
Мы добавили в DartPad ещё одну удобную фичу. Раньше он всегда запускал последнюю стабильную версию. Теперь можно выбрать свежие релизы в бета-канале или предыдущий стабильный релиз (который называется «old channel») в новом пункте меню «Channel» в строке состояния.
Эта фича пригодится, если вы, например, пишете пост в блоге о свежем релизе, и последняя стабильная версия для него недостаточно свежая.
Недавно мы прекратили обновлять канал dev. Оказалось, что им пользуется 3% Flutter-разработчиков. Наши ресурсы ограничены, поэтому мы официально начинаем его сворачивать. Если вы всё время проводите в стабильном канале (как и более 90% Flutter-разработчиков), разницы вы не заметите.
Выбрать, какой канал вы хотите использовать, можно с помощью команды flutter channel. Вот что думает о каждом канале команда Flutter:
Я — Евгений Сатуров, Head of Flutter в Surf и ведущий Flutter Dev Podcast. Представляю перевод официальной статьи про свежий релиз Flutter 2.8, дополненный моими комментариями.
Вот в северное полушарие и пришла та самая пора: листва опадает, на улице холодает, и последний стабильный релиз этого года уже тут как тут. Всем привет и добро пожаловать во Flutter 2.8! Этот релиз стал результатом труда 207 контрибьюторов и 178 рецензентов, которым удалось смёрджить 2 424 PR и решить 2976 проблемных моментов.
Благодаря коллективной работе контрибьюторов:
- существенно улучшилась производительность движка и Flutter DevTools,
- вышел стабильный релиз Google Mobile Ads SDK для Flutter,
- появилась целая гора новых фич и усовершенствований Firebase, WebView 3.0,
- добавилась новая партия пакетов Flutter Favorite,
- много обновлений для десктопа уже на пути к стабильному релизу.
Производительность
На первом месте для нас во Flutter стоит качество. Существенную часть времени тратим на то, чтобы Flutter работал как можно плавнее и устойчивее на самых разных устройствах, поддерживаемых фреймворком.Запуск
Улучшения коснулись задержки запуска. Их мы протестировали на Google Pay — огромном и крайне популярном приложении, в котором более одного миллиона строк кода. Последние улучшения помогли сократить задержку при запуске Google Pay на 50% на слабых Android-устройствах и на 10% — на мощных.Мы ослабили влияние Flutter на политику сборки мусора Dart VM: это помогло избежать несвоевременного запуска циклов сбора при запуске приложения. К примеру, теперь перед рендерингом первого кадра на Android Flutter уведомляет Dart VM только о сигналах нехватки памяти уровня TRIM_LEVEL_RUNNING_CRITICAL и выше. При локальном тестировании это изменение в некоторых случаях сократило время отрисовки первого кадра на слабых устройствах на целых 300 мс.
В предыдущих релизах мы подходили к разработке с чрезмерной осторожностью, поэтому Flutter блокировал поток платформы при создании платформенных view. Благодаря рациональным аргументам разработчиков и результатам тестирования, мы выяснили, что в некоторых случаях сериализации можно избежать. Это сокращает задержку запуска Google Pay на слабом устройстве более чем на 100 мс.
Раньше запуск дефолтного менеджера шрифтов вызывал искусственную задержку при запуске первого Dart-изолята. Мы сократили задержку: отложили запуск дефолтного менеджера шрифтов, чтобы он происходил одновременно с запуском Isolate в Dart.
Комментарий Евгения Сатурова
Мы действительно заметили, что в последних версиях Flutter появились ощутимые проблемы со скоростью запуска приложения. Проблема проявилась в одном из наших флагманских проектов, у команды которого теперь есть особенная мотивация для скорейшей миграции на новую версию фреймворка. Очень радует, что Flutter-команда стала уделять более пристальное внимание критическим проблемам с производительностью. Фикс прилетел очень своевременно.
Память
Flutter-разработчики, занимавшиеся устройствами с ограниченной памятью, столкнулись с проблемой при трассировке производительности. Flutter бросался загружать «сервисный изолят» Dart VM: AOT-код связывался с приложением таким образом, что Flutter считывал их в память одновременно.Для Android в релизе 2.8 мы выделили сервисному изоляту Dart VM свой собственный bundle, который можно загружать отдельно. Благодаря этому в приложении удаётся сэкономить до 40 мб памяти — пока не потребуется использовать сервисный изолят.
Кроме того, мы сократили объём требуемой памяти на 10%: научили Dart VM сообщать ОС, что страницы памяти, используемые AOT-программой, содержат сохранённую в файл информацию. Она, скорее всего, больше не будет считываться в память. В результате страницы, которые были заняты копией данных, можно очистить и переиспользовать.
Профилирование
Иногда разработчикам требуется посмотреть данные о производительности Flutter или статистику в релизных сборках, чтобы подробнее разобраться, какие проблемы с производительностью есть в приложении.В стабильном релизе 2.8 события трассировки отправляются в регистратор системной трассировки Android, если его активировали при запуске приложения. Более того, события отправляются, даже если это релизная сборка Flutter-приложения.
События трассировки во Flutter теперь отображаются (снизу) в инструментах регистрации системной трассировки для Android
Чтобы создавать анимации с меньшим количеством лагов, некоторые из вас хотели получать при трассировке производительности больше информации о кэшировании растровых изображений. Благодаря ему Flutter переиспользует фрагменты тяжёлых изображений — вместо того, чтобы перерисовывать их для каждого кадра. Новые события потоков в статистике производительности позволяют отследить жизненный цикл кэшированных растровых изображений.Комментарий Евгения Сатурова
Наши разработчики, которые раньше писали под Android, пожалуй, больше всего скучают по нативному профайлеру, которым может похвастаться Android Studio. Это действительно мощный инструмент, который… совершено бесполезен во Flutter-разработке. Был. До выхода 2.8. Примечательно, что параллельно с развитием своей экосистемы инструментов, Flutter не забывает встраиваться и в инструменты родственных платформ.
Flutter DevTools
Для отладки проблем с производительностью в этом релизе DevTools мы добавили новую фичу расширенной трассировки «Enhance Tracing». С её помощью можно диагностировать причины лагов UI: ресурсозатратные сборки, вёрстку и отрисовку объектов.Если активировать любую из фич трассировки на картинке, на временной шкале будут отображаться новые события для собранных виджетов, а также скомпонованных и отрисованных объектов, если такие есть.
В этом релизе DevTools добавились новые возможности профилирования производительности при запуске приложения. Новая статистика содержит анализ нагрузки ЦП: начиная с инициализации Dart VM и заканчивая рендерингом первого кадра на Flutter. Как только вы нажмёте кнопку «Profile app start up» («Профилировать запуск приложения») и статистика по запуску приложения загрузится, программа выберет для неё тег «AppStartUp» («Запуск приложения»). Профилирование загрузки приложения также можно запустить, выбрав сам тег (если он есть) из списка доступных пользовательских тегов. Так вы получите доступ к данным профилирования при запуске приложения.
Платформенные view из веба
Android и iOS — не единственные платформы, которым достанутся обновления, повышающие производительность. В этом релизе мы также улучшили производительность платформенных view для Flutter web.С помощью платформенных view можно размещать в приложении компоненты нативного UI из платформы используемого вами устройства. Flutter web позволяет поместить HTML элементы в веб-приложение на Flutter с помощью виджета HtmlElementView. Если вы пользуетесь веб-версиями плагина google_maps_flutter, плагина video_player или следуете рекомендациям команды Flutter об оптимизации отображения картинок в веб, вы пользуетесь платформенными view.
Чтобы встроить платформенные view, в прошлых версиях Flutter приходилось создавать новый холст каждый раз. Чем больше платформенных view, тем больше холстов. Каждый новый холст требует очень много ресурсов, так как занимает всё окно целиком. В этом релизе Flutter переиспользует холсты, созданные для предыдущих view. В результате, вместо того, чтобы тратить в 60 раз больше ресурсов каждую секунду, приложение требует их один раз за время работы. Можно добавлять в веб-приложение несколько экземпляров HtmlElementView: это не снизит производительность и уменьшит лаги при скроллинге страницы с платформенными view.
Комментарий Евгения Сатурова
Flutter for Web — это пока не наша история. Мы подходим к выбору технолгий для нашего стека очень аккуратно. Хотя по нам и не скажешь: кто ещё писал на Flutter уже в начале 2019 года? А мы писали.
Но в случае с Flutter for Web — это другое. Имеющиеся сейчас проблемы с поддержкой фреймворком веб-платформы уходят довольно глубоко в фундаментальные принципы, на которых он основан. Можно дошлифовать производительность и UX, а вот что делать с адаптацией к SEO и оптимизацией скорости загрузки приложения, пока непонятно.
А вот оптимизация платформенных компонентов для веба — это отлично. Но это капля в море.
Экосистема
Flutter — это не просто фреймворк, движок и инструменты. На pub.dev представлено более 20 тысяч совместимых с Flutter пакетов и плагинов, и каждый день их количество растёт. То, с чем Flutter разработчики взаимодействуют ежедневно, – лишь верхушка огромной экосистемы. Давайте посмотрим, что нового успело произойти в экосистеме Flutter с предыдущего релиза.Flutter Ads в общем доступе
Начнём с релиза Google Mobile SDK для Flutter в общий доступ в ноябре.[IMG alt="Баннерная реклама | Полноэкранная реклама | Видеореклама с вознаграждением | Нативная реклама | Реклама при запуске приложения
Google Mobile Ads SDK для Flutter"]https://habrastorage.org/r/w1560/ge...0d3ba00ed1e62c0c2ffc7774fb.png[/IMG]Баннерная реклама | Полноэкранная реклама | Видеореклама с вознаграждением | Нативная реклама | Реклама при запуске приложения Google Mobile Ads SDK для Flutter
Релиз поддерживает пять форматов рекламы, интеграцию с AdMob и Ad Manager и включает бета-версию новой фичи для размещения рекламы от посредников. С её помощью можно оптимизировать производительность приложения. Более подробно об интеграции Google Рекламы во Flutter-приложение и других способах монетизации рассказываем на новой страничке о монетизации на flutter.dev.
WebView 3.0
Ещё один новый релиз, вышедший в этот раз вместе с Flutter, — версия 3.0 плагина webview_flutter. Мы подняли номер версии: в ней добавилось много новых фич, а ещё она, скорее всего, существенным образом изменит принцип работы webview на Android.В предыдущих версиях webview_flutter режим гибридной компоновки («Hybrid Composition») уже был доступен, но не по умолчанию. Гибридная компоновка решает ряд проблем, существовавших в предыдущем дефолтном режиме «Virtual Display». Учитывая отзывы пользователей и статистику багов, мы решили, что пришло время сделать гибридную компоновку дефолтной. Кроме того, с webview_flutter добавилось несколько фич, о которых многие просили:
- Поддержка POST и GET для наполнения контентом (4450, 4479, 4480, 4573)
- Загрузка HTML из файлов и строк с текстовой информацией (4446, 4486, 4544, 4558)
- Поддержка прозрачного фона (3431, 4569, 4570)
- Запись информации в cookies до загрузки контента (4555, 4556, 4557)
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:webview_flutter_web/webview_flutter_web.dart';
void main() {
runApp(const MaterialApp(home: HomePage()));
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
void initState() {
super.initState();
// required while web support is in preview
if (kIsWeb) WebView.platform = WebWebViewPlatform();
}
@override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(title: const Text('Flutter WebView example')),
body: const WebView(initialUrl: 'https://flutter.dev'),
);
}
При запуске в веб работает так, как и ожидается:
Следует заметить, что у текущей реализации webview_flutter для веб есть ряд ограничений. Она написана с помощью iframe: он поддерживает только загрузку простых URL и не умеет контролировать или взаимодействовать с загруженным контентом (подробнее читайте в the webview_flutter_web README). Однако по просьбе сообщества мы предоставляем доступ к webview_flutter_web в виде неофициального плагина. Если хотите его попробовать, добавьте следующую строку к pubspec.yaml:
dependencies:
webview_flutter: ^3.0.0
webview_flutter_web: ^0.1.0 # add unendorsed plugin explicitly
Если у вас возникла проблема с webview_flutter v3.0, пишите во Flutter репозиторий с пометкой «webview issue». Если же вы ещё не пользовались webview, прочтите новый codelab по webview, в котором пошагово расписан процесс внедрения веб-контента в приложении на Flutter.
Flutter Favorites
Комитет по экосистеме Flutter провёл очередную встречу и включил следующие пакеты во Flutter Favorite:- Три кастомных пакета маршрутизации для нового Router API: beamer, routemaster и go_router.
- drift — получившая новое имя функциональная и популярная реактивная библиотека для управления базами данных во Flutter и Dart, созданная на основе sqlite.
- freezed — «языковой патч» для Dart, содержащий простой синтаксис для описания моделей, клонирования объектов, поиска по шаблону и других действий.
- dart_code_metrics.
- Несколько красивых пакетов для графического интерфейса: flex_color_scheme, flutter_svg, feedback, toggle_switch и auto_size_text.
Комментарий Евгения Сатурова
Попадание пакета в программу сертификации Flutter Favorite — большое событие. На данный момент таких пакетов всего 64 (из 22 тысяч, доступных на pub.dev). Лычка Flutter Favorite — это безоговорочное признание ценности и качества пакета сообществом и создателями самого фреймворка.
Тем радостнее мне наблюдать dart_code_metrics среди пакетов, наконец получивших этот почётный статус. dart_code_metrics был создан бывшим членом нашей дружной команды (привет, Дима!). А наш Flutter-разработчик Влад Коношенко активно контрибьютит в dart_code_metrics и по сей день.
Мы используем dart_code_metrics для мониторинга качества кодовой базы наших проектов, и рекомендуем делать это вам.
Платформо-специфичные пакеты
Если вы создаёте пакет, вам необходимо решить, какие платформы поддерживать. Если плагин содержит платформо-специфичный нативный код, это можно сделать с помощью свойства pluginClass в pubspec.yaml проекта, где указывается нативный класс, обеспечивающий выполнение фичи:flutter:
plugin:
platforms:
android:
package: com.example.hello
pluginClass: HelloPlugin
ios:
pluginClass: HelloPlugin
Однако Dart FFI не стоит на месте: сейчас можно внедрить платформо-специфичную функциональность с помощью кода, на 100% состоящего из Dart, как сделали с пакетом path_provider_windows. Даже если пакет не имеет нативных классов, вы всё ещё можете указать, что он поддерживает определённую платформу. В таком случае используйте свойство dartPluginClass:
flutter:
plugin:
implements: hello
platforms:
windows:
dartPluginClass: HelloPluginWindows
С помощью этих свойств вы можете указать, что пакет поддерживает только определённые платформы, даже если в приложении вообще нет нативного кода. Также вам необходимо указать класс Dart плагина. Подробнее об этом можно прочитать в документах о платформенных реализациях на чистом Dart на flutter.dev.
Firebase
Ещё одна важная часть экосистемы Flutter — это FlutterFire. В этом релизе мы добавили ряд новых фич, благодаря которым писать приложения с помощью Flutter и Firebase станет проще:- Все плагины FlutterFire переходят из беты в стабильный канал.
- Поддержка нескольких сервисов Firebase в DartPad.
- Новые библиотеки, с которыми станет легче собирать UI для аутентификации и отправлять запросы в Firestore в реальном времени.
- Новая функциональность Firestore Object/Document Mapping для Flutter доступна в альфа-канале.
Стабильный канал
Почти все плагины FlutterFire уже перешли из беты в стабильный канал.Плагины, которые перешли в стабильный канал для Android, iOS и веб, включают:
- аналитику (Analytics),
- динамические ссылки (Dynamic Links),
- сообщения внутри приложений (In-App Messaging),
- мониторинг производительности (Performance Monitoring),
- базу данных, синхронизированных в реальном времени (Realtime Database)
- дистанционную настройку приложений (Remote Config).
Realtime Database, Analytics и Remote Config теперь — полноценные плагины, готовые к использованию в продакшене.
Инициализация Firebase через Dart
С переходом пакетов в стабильный канал мы добавили возможность инициализировать Firebase на любой из поддерживаемых платформ средствами Dart:import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart'; // generated via `flutterfire` CLI
Future<void> main() async {
// initialize firebase across all supported platforms
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
runApp(MyApp());
}
Программный код инициализирует приложение Firebase способом, соответствующим определённой поддерживаемой платформе, согласно информации в файле firebase_options.dart:
static const FirebaseOptions web = FirebaseOptions(
apiKey: 'AIzaSyCZFKryCEiKhD0JMPeq_weJguspf09h7Cg',
appId: '1:111079797892:web:b9195888086158195ffed1',
messagingSenderId: '111079797892',
projectId: 'flutterfire-fun',
authDomain: 'flutterfire-fun.firebaseapp.com',
storageBucket: 'flutterfire-fun.appspot.com',
measurementId: 'G-K029Y6KJDX',
);
Чтобы подробнее узнать о структуре данных каждого способа инициализации для той или иной платформы, ознакомьтесь с новым инструментом flutterfire CLI.Комментарий Евгения Сатурова
Изменение, которое прошло малозаметным, но… как же это прекрасно. Лишний раз не лезть в дебри нативных модулей Flutter-проекта всегда приятно. Работать с Firebase стало ещё проще, чем раньше. Экономия времени даже на таких мелочах позволяет сфокусироваться на главном — на качестве и технологичности продуктов.
Но причина моей радости не только в этом улучшении. Ниже вы узнаете про FlutterFire CLI, который возмужал настолько, что позволяет вообще забыть про веб-интерфейс Firebase навсегда. Даже в том случае, если вы ещё не создали Firebase-проект.
Этот инструмент отправляется в данные в платформо-специфичных вложенных папках и ищет уникальный bundle ID. Затем использует его, чтобы найти подробную информацию по определённому проекту Firebase для соответствующего платформо-специфичного приложения или даже создать новый проект Firebase и новые платформо-специфичные приложения, если таких нет.
Какая в этом польза? Больше не надо скачивать и добавлять json-файл в Android-проект, скачивать и добавлять plist файл в iOS и macOS проекты или копипастить код в index.html web-проекта. Не важно, какую из поддерживаемых Firebase платформ вы выбрали, — этот кусочек кода на Dart инициализирует Firebase для приложения.
Однако, возможно, это не единственная инициализация, которую надо будет выполнить, чтобы FlutterFire-приложение заработало. Например, может потребоваться интегрировать символы Crashlytics в Android или iOS сборку. Однако с любым новым Firebase-проектом на это должны уйти считанные минуты.
Используем Firebase с DartPad
Так как FlutterFire инициализируется исключительно средствами Dart, Firebase теперь можно использовать прямо внутри DartPad.В этом примере показано небольшое приложение-чат, которое использует Flutter, Firebase и DartPad. Их уже можно использовать, не устанавливая. Поддержка Firebase в DartPad уже включает основные API, аутентификацию и Firestore. Со временем в DartPad будут появляться новые сервисы Firebase.
Помимо этого, поддержка FlutterFire в DartPad даёт возможность использовать версию DartPad, встроенную прямо в документы.
В этом примере — документы для Cloud Firestore, в одном из которых написан код для примера приложения. Его можно запускать и редактировать прямо в браузере. Здесь можно создавать тестовый проект или даже копипастить код. Всё необходимое будет под рукой.
Firebase UI
У большинства приложений, которые интегрируются с Firebase, есть процесс аутентификации. В том числе — возможность залогиниться с помощью электронной почты и пароля или через аккаунт в другом сервисе, например, Google.Firebase Authentication позволяет создавать новый аккаунт в два счёта, подтверждать адрес электронной почты, менять пароль, а в некоторых случаях — выполнить двухэтапную верификацию через SMS, залогиниться через номер телефона или даже объединить несколько пользовательских аккаунтов в один.
Пакет flutterfire_ui умеет воплощать основные сценарии аутентификации с минимальным количеством кода. Представим, что в проекте Firebase доступна аутентификация через email и Google-аккаунт:
С этим пакетом можно создать процесс аутентификации следующим образом:
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutterfire_ui/auth.dart';
import 'firebase_options.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) => MaterialApp(
home: AuthenticationGate(),
);
}
class AuthenticationGate extends StatelessWidget {
const AuthenticationGate({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) => StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
// User is not signed in - show a sign-in screen
if (!snapshot.hasData) {
return SignInScreen(
providerConfigs: [
EmailProviderConfiguration(),
GoogleProviderConfiguration(
clientId: 'xxxx-xxxx.apps.googleusercontent.com',
),
],
);
}
return HomePage(); // show your app’s home page after login
},
);
}
Этот код инициализирует Firebase. Если он заметит, что пользователь ещё не залогинился, покажет экран регистрации. В виджете SigninScreen есть возможность аутентификации через email и Google-аккаунт. Кроме того, код анализирует аутентификационное состояние пользователя с помощью пакета firebase_auth: как только пользователь зарегистрируется, вы сможете показать ему все остальные экраны приложения. С помощью этого кода вы получаете рабочий процесс авторизации для всех платформ, поддерживаемых Firebase: Android, iOS, веб и macOS.
Выполнив ещё несколько действий, вы с лёгкостью можете вставить изображение и какой-нибудь кастомный текст (подробнее в документации) и таким образом выстроить полноценный процесс входа в приложение:
Если у пользователей уже есть email и пароль, они могут их ввести и войти в приложение. Если они используют авторизацию через Google, приложение покажет им классический процесс авторизации через Google-аккаунт, независимо от того, мобильная это версия, веб- или десктопная. Если у них ещё нет аккаунта, они могут нажать на кнопку на экране входа в приложение и перейти на экран регистрации.
После входа в приложение или регистрации, приложение может показать пользователю экраны валидации электронной почты, смены забытого пароля, выхода из аккаунта и привязки аккаунта социальной сети для последующей аутентификации. Вход через email работает на всех платформах. Также есть возможность авторизации через аккаунты Google, Facebook и Twitter. Она частично поддерживается для Apple, но не работает на Android. Аутентификация с flutterfire_ui поддерживает несколько сценариев и схем навигации. Помимо этого, у flutterfire_ui есть возможность кастомизации и локализации. Подробная информацию и примеры — в документации на firebase.flutter.dev.
Аутентификация — не единственная связанная с Firebase UI фича, которую поддерживает flutterfire_ui. Чтобы в реальном времени показать пользователю список данных из запроса Firebase с возможностью бесконечной прокрутки, мы включили в этот релиз FirestoreListView, который можно добавить в приложение с активным запросом следующим образом:
class UserListView extends StatelessWidget {
UserListView({Key? key}) : super(key: key);
// live Firestore query
final usersCollection = FirebaseFirestore.instance.collection('users');
@override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(title: const Text('Contacts')),
body: FirestoreListView<Map>(
query: usersCollection,
pageSize: 15,
primary: true,
padding: const EdgeInsets.all(8),
itemBuilder: (context, snapshot) {
final user = snapshot.data();
return Column(
children: [
Row(
children: [
CircleAvatar(
child: Text((user['firstName'] ?? 'Unknown')[0]),
),
const SizedBox(width: 8),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Text(
'${user['firstName'] ?? 'unknown'} '
'${user['lastName'] ?? 'unknown'}',
style: Theme.of(context).textTheme.subtitle1,
),
Text(
user['number'] ?? 'unknown',
style: Theme.of(context).textTheme.caption,
),
],
),
],
),
const Divider(),
],
);
},
),
);
}
Так список выглядит в приложении:
А если вы хотите, чтобы пользователи могли создавать, читать, обновлять и удалять элементы таблицы, в FirestoreDataTable уже появляются такие возможности:
class FirestoreTableStory extends StatelessWidget {
FirestoreTableStory({Key? key}) : super(key: key);
// live Firestore query
final usersCollection = FirebaseFirestore.instance.collection('users');
@override
Widget build(BuildContext context) {
return FirestoreDataTable(
query: usersCollection,
columnLabels: const {
'firstName': Text('First name'),
'lastName': Text('Last name'),
'prefix': Text('Prefix'),
'userName': Text('User name'),
'email': Text('Email'),
'number': Text('Phone number'),
'streetName': Text('Street name'),
'city': Text('City'),
'zipCode': Text('Zip code'),
'country': Text('Country'),
},
);
}
}
Вот как это работает:
Подробнее об аутентификации, list view и таблицах данных — в документации по flutterfire_ui. Это предварительный релиз, и мы добавим в него новые фичи. Если у вас есть вопрос или вы знаете, какую фичу нужно добавить, перейдите в репозиторий на GitHub и сообщить о баге или задать вопросы в разделе обсуждений.
Комментарий Евгения Сатурова
Если вы рассматриваете Flutter в первую очередь как инструмент для прототипирования или быстрой сборки MVP, значимость flutterfire_ui трудно переоценить.
В наших проектах пакету вряд ли найдётся широкое применение. Чем компоненты более верхнеуровневые, тем больше они несут на борту различных ограничений. А мы любим Flutter совсем не за это, а как раз наоборот — за свободу и гибкость.
Firestore Object/Document Mapping
И последняя, но от того не менее важная фича для интеграции Firebase с Flutter — это релиз Firestore Object/Document Mapper в альфа-канале. Цель Firestore ODM – повысить продуктивность Flutter-разработчиков, упростив работу с Firestore с помощью уже знакомых структурно упорядоченных объектов и методов из безопасной системы типов. С помощью кодогенерации Firestore ODM дорабатывает синтаксис, необходимый для взаимодействия с документами и коллекциями. Это позволяет разработчику моделировать данные типобезопасным способом:@JsonSerializable()
class Person {
Person({required this.name, required this.age});
final String name;
final int age;
}
@Collection<Person>(‘/persons’)
final personsRef = PersonCollectionReference();
С помощью данных типов можно делать запросы типобезопасным способом:
personsRef.whereName(isEqualTo: 'Bob');
personsRef.whereAge(isGreaterThan: 42);
Помимо этого, ODM поддерживает возможность описания строго типизированных подколлекций. С его помощью можно оптимизировать пересборку виджетов, используя фичу select. Об этом и многом другом — в документации к Firestore ODM.
Будем рады вашим отзывам. Чтобы оставить отзыв или задать вопрос, присоединяйтесь к треду о Firestore ODM в обсуждении FlutterFire.
Десктопная версия
В релизе Flutter 2.8 мы сделали ещё один большой шаг на пути к стабильному релизу для Windows, macOS и Linux. Задали высокую планку качества: в том числе поддерживаем интернационализацию и локализацию, как в случае с недавно вышедшей поддержкой ввода китайских иероглифов, корейских иероглифов, и кандзи. Или как в случае с тесной интеграцией со специальными возможностями в Windows.Мы считаем, что для Flutter недостаточно работать на десктопных устройствах в стабильном канале (что уже возможно в бета-версии, если открыть доступ фиче-флагом). Он должен подходить для разных языков и культур мира, а также для людей с разными возможностями. Пока что мы не добились нужного результата, но идём к цели!
Мы не прекращаем работать над стабильной десктопной версией. Например, чтобы добиться синхронного отклика, мы полностью пересмотрели архитектуру взаимодействия Flutter с событиями, которые он получает от клавиатуры. Благодаря этому виджет теперь может распознавать нажатие на клавишу и останавливать прохождение сигнала дальше по дереву.
Благодаря работе, проделанной во Flutter 2.5 и Flutter 2.8, мы пофиксили баги и регрессионные ошибки. Продолжаем реорганизовывать обработку данных с клавиатуры на различных устройствах и рефакторить процесс форматирования текста во Flutter: это необходимо для десктопных приложений, где информация в основном вводится с помощью клавиатуры.
Кроме того, продолжаем расширять поддержку visualDensity во Flutter и применяем выравнивание к диалогам, чтобы сделать UI удобнее для десктопных устройств.
Команда Flutter — не единственная, кто работает над десктопной версией Flutter. Команда разработчиков для десктопов в Canonical в сотрудничестве с Invertase занимается реализацией наиболее популярных плагинов Firebase для Flutter на Linux и Windows. И это только один из примеров.
Подробнее о предварительном релизе — в блоге Invertase.
DartPad
Рассказ о релизе Flutter будет неполным, если не упомянуть, как мы усовершенствовали инструментарий. В этом посте сконцентрируемся на улучшениях в DartPad. Крупнейшее из них — расширение поддержки пакетов: теперь можно импортировать 23 пакета. Помимо ряда сервисов Firebase, в список вошли популярные пакеты: bloc, characters, collection, google_fonts и flutter_riverpod. Команда DartPad продолжает добавлять новые пакеты. Чтобы посмотреть, какие пакеты поддерживает DartPad, щёлкните по иконке информации в нижнем правом углу.Чтобы посмотреть, какие пакеты мы планируем добавить в DartPad в будущем, переходите на статью в Dart wiki.
Мы добавили в DartPad ещё одну удобную фичу. Раньше он всегда запускал последнюю стабильную версию. Теперь можно выбрать свежие релизы в бета-канале или предыдущий стабильный релиз (который называется «old channel») в новом пункте меню «Channel» в строке состояния.
Эта фича пригодится, если вы, например, пишете пост в блоге о свежем релизе, и последняя стабильная версия для него недостаточно свежая.
Комментарий Евгения Сатурова
Я долго не понимал смысл существования DartPad, но сейчас из невнятного блокнота с возможностью выполнить несложный код, он постепенно превращается в весьма функциональный инструмент. Мы уже используем его на собеседованиях, для проверки гипотез в ходе брейн-штормов и сессий технического проектирования.
Прощаемся с каналом dev
Во Flutter «каналы» отличаются тем, насколько быстро в фреймворк и движок вносятся изменения: канал «stable» претерпевает минимум изменений, а канал «master» меняется максимально часто.Недавно мы прекратили обновлять канал dev. Оказалось, что им пользуется 3% Flutter-разработчиков. Наши ресурсы ограничены, поэтому мы официально начинаем его сворачивать. Если вы всё время проводите в стабильном канале (как и более 90% Flutter-разработчиков), разницы вы не заметите.
Выбрать, какой канал вы хотите использовать, можно с помощью команды flutter channel. Вот что думает о каждом канале команда Flutter:
- Канал stable представляет самые качественные из имеющихся сборок. Новые сборки выходят (примерно) раз в квартал, а в промежутках мы выпускаем hotfix критических ошибок. Этот канал – «медленный»: предлагаемые решения безопасны, проработаны и прослужат долго.
- Канал beta – динамичная альтернатива стабильному каналу для тех, кто чувствует себя комфортно в часто меняющейся обстановке. На данный момент релизы выходят раз в месяц, а перед релизом канал стабилизируется. Этот канал – «быстрый». Если мы поймём, что канал dev удовлетворял потребностям, которым не отвечает beta-канал, мы возможно изменим свой подход к beta-каналу. Например, будем выпускать обновления в beta-канале чаще или сократим число тестов и hot fix.
- Канал master – канал активной разработки. На нём нет поддержки, но мы прогоняем его через обширный набор модульных тестов. Этот канал подходит для контрибьюторов и продвинутых пользователей, которых не пугают нестабильные сборки. На этом канале мы постоянно что-то делаем и ломаем. И чиним тоже постоянно.
Комментарий Евгения Сатурова
Еще полтора-два года назад некоторые наши проекты действительно «сидели» на dev-канале. В те времена Flutter был сыроват, а квартальный релизный цикл стабильного канала никак не позволял быстро получить исправления некоторых неприятных багов фреймворка (за хотфиксы респект, но спасали они не всегда).
Мы уже давно официально не рекомендуем использовать dev, просто потому что это больше не имеет особого смысла. Теперь dev-каналу официально пришёл конец.
Критические изменения
Мы стремимся свести число критических изменений к минимум в каждом релизе. В релизе Flutter 2.8 критических изменений нет, кроме устаревших API, которые получили статус «deprecated» и были удалены в соответствии с нашей политикой критических изменений.- 90292 Удалены autovalidate
- 90293 Удалён FloatingHeaderSnapConfiguration.vsync
- 90294 Удалён AndroidViewController.id
- 90295 Удалён BottomNavigationBarItem.title
- 90296 Удалены классы для форматирования вводимого текста
Подведём итоги
Провожая 2021 год, наша команда Flutter хотела бы искренне поблагодарить Flutter-сообщество за труд и поддержку. И хотя мы безусловно развиваем Flutter для того, чтобы с каждым годом им пользовалось всё больше разработчиков по всему миру, не будет преувеличением, если я скажу, что мы бы никогда не справились с задачей без вашей помощи. Сообщество Flutter — уникальные люди, и мы благодарны вам за ваши старания. Чудесных вам праздников! Увидимся в новом году!Flutter 2.8: что нового
Повышение производительности, новые фичи Firebase, состояние десктопной версии, новые инструменты и многое другое. Я — Евгений Сатуров, Head of Flutter в Surf и ведущий Flutter Dev...
habr.com