头图

Winter in the northern hemisphere is here, yellow leaves and temperature are falling with the wind. The last stable version of Flutter at the end of the year, has quietly arrived in front of you . Let us hello to 161bac0de5bc6c Flutter 2.8

This update contains the 207 contributors and 178 reviewers . All of them jointly produced 2424 PR , and closed 2976 issue . Special thanks to the most prominent community contributor in this release: Flutter development engineer Bartosz Selwesiuk from VGV, who submitted 23 PRs for the camera plug-in of the web platform.

All the above outputs have greatly improved the performance of the Flutter engine and developer tools (DevTools). At the same time, it also brought the stable release of the Flutter version of the Google mobile advertising SDK, a series of new features for Firebase and Optimization, Flutter WebView 3.0, new Flutter Favorite package, a big step towards a stable version of the desktop, and a new version of DartPad that supports more packages. Let's take a look together!

Performance improvement

Flutter's primary goal is to ensure its quality as always. We spent a lot of time to ensure that Flutter runs smoothly and stably on a variety of devices.

Application startup performance

This update optimizes the delay of application startup. We have tested the GPay application with more than one million lines of code to ensure that the changes are effective in the actual production application. These changes reduced GPay's startup time on low-end Android devices by about 50% and high-end devices by about 10% .

We have also made some improvements to Flutter's GC strategy for calling Dart VM to avoid untimely GC during program startup. For example, before the first frame is rendered on the Android device, Flutter only informs Dart VM that there is memory pressure when the TRIM_LEVEL_RUNNING_CRITYCAL and higher level signals appear. In the local test, low-end Android device is reduced by about 300ms .

In previous versions of Flutter, considered prudent , when creating a platform PlatformView blocks the thread. After careful reasoning and testing , we deleted the partial serialization step, which reduced on low-end devices by at least 100ms .

For a long time, initializing the default font manager before initializing the first Dart isolate introduces artificial delays. Since it is the primary delay bottleneck, delays the initialization of the default font manager to run at the same time as the first Dart isolate, which reduces the startup delay and makes all the above startup optimizations more obvious.

Application memory

Since Flutter will load the service isolate of the Dart VM as quickly as possible, and load it into the memory together with the AOT code bound in the app, this will cause Flutter developers to be difficult to track Memory indicator . In the Flutter 2.8 version, the service isolate of the Dart VM on the Android device has been split into a separate bundle , which can be loaded separately, reducing the memory usage of about 40MB before it is loaded. The original Dart VM sent a notification of the memory usage of the AOT program to the operating system, which has been transferred to a file that does not need to be read multiple times, and the subsequent memory usage has been further reduced by about 10%. Therefore, the memory that previously saved a copy of the file data can be recycled and used for other purposes.

Performance analysis

In some scenarios, developers hope to see Flutter and Android performance tracking events at the same time, or view tracking events in production mode to better understand application performance issues. For this requirement, Flutter 2.8 can now choose to send performance tracking events to Android's event recorder after the application is launched, and the same is true in production mode.

Flutter 性能追踪事件现在显示在 Android systrace 记录工具中(底部)

In addition, some developers want more performance tracking information about the behavior of raster caching to reduce lag when creating animation effects, which allows Flutter to quickly reuse expensive, reusable images instead of redrawing them. stream event in performance tracking allows developers to track the life cycle of raster cached pictures.

Flutter developer tools

For debugging performance issues, the new version of DevTools has added a new "enhanced tracking" function to help developers diagnose UI freezes caused by expensive build, layout, and drawing operations.

After enabling any of the tracking functions, the timeline will display Widget construction, RenderObject layout and RenderObject drawing events as appropriate.

In addition, the new version of the developer tools also adds support for the analysis of application startup performance. This configuration file contains the CPU samples from the initialization of the Dart VM to the first frame of Flutter rendering. After you press the "Profile app start up" button and load the application startup profile, you will see the "AppStartUp" tab selected for the profile. You can also load the application startup configuration file by selecting this user tag filter (if it exists) in the list of available user tags. Selecting this tab will display the profile data of your app launch.

Platform view of the web platform (PlatformView)

Not only the performance of Android and iOS platforms have been improved, this release also includes performance optimizations for the Flutter Web platform view. The platform view is the medium for embedding UI components from the host platform to Flutter. Flutter Web uses the HtmlElementView widget to achieve this feature, allowing you to embed HTML elements in Flutter Web applications. If you are using google_maps_flutter plug or video_player Web version of the plug, or if you are following Flutter team on how to optimize the image displayed on the network suggested, it means you are already using the platform view.

In the previous version of Flutter, embedding a platform view would create a new canvas, and each embedded platform view would add a new canvas.
Creating additional canvases is a very performance-consuming operation, because the size of each canvas is equal to the entire window. In Flutter 2.8, created by the previous platform view. Therefore, you will not incur a cost of 60 times per second during the entire life cycle of the application, but the cost of only one creation. This means that you can have multiple HtmlElementView instances in your web application without performance degradation, and at the same time, you can reduce scrolling lag when using platform views.

Ecology

Flutter is more than just frameworks, engines, and tools-there are currently more than 2w Flutter-compatible packages and plugins on pub.dev, and they are increasing every day. A large number of daily operations of Flutter developers are also part of the huge ecosystem, so let's take a look at what has changed in the Flutter ecosystem since the last version.

Google ads for Flutter ads

The first and most important thing is that Google Mobile SDK for Flutter was officially released in . This version supports 5 ad formats, integrates AdMob and Ad Manager support, and includes a beta version of a new transit function that can help you optimize the effectiveness of your ads. For information about Google Ads for more information Flutter integrated into the application and other monetization options, please see page on Flutter website .

WebView 3.0

Another new version of Flutter this time is the 3.0 version webview_flutter plug-in Because of the increase in the number of new features, we have increased the major version number, but also because the way the web view works on Android may have undergone major changes. In the previous webview_flutter , Hybrid composition is already available, but it is not the default. And now it fixes many problems that used to run in virtual display mode by default.
Based on user feedback and our issue tracking, we think it is time to make Hybrid composition the default setting. In addition, webview_flutter also adds some highly popular functions:

  • Supports the use of POST and GET to load content
  • Load file or string content as HTML
  • Support transparent background
  • Set cookies before loading content

In addition, in version 3.0, webview_flutter provides preliminary support for the new platform: Flutter Web. Many people have asked for the ability to host web views in Flutter web applications, which allows developers to build mobile or web applications with a single source code library. What is it like to host a web view in a Flutter web application? From the point of view of writing code, it is actually the same:

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'),
  ;
}

When running on Flutter Web, it will work as you expect:

Please note that the current webview_flutter has many limitations because it is built using iframes,
Iframes only support simple URL loading, and cannot control or interact with loaded content.
However, due to high demand, we decided to provide webview_flutter_web as an unapproved plug-in.
If you want to try it, please add the following to your pubspec.yaml :

dependencies:
  webview_flutter: ^3.0.0
  webview_flutter_web: ^0.1.0 # 显式依赖未经认可的插件

If you webview_flutter v3.0, whether it is about the web platform or not, please in the Flutter warehouse at 161bac0de5c0c9. Also, if you have not used before webview or want a refresher, check out new Codelab webview , it will take you step by step through hosting of Web content in Flutter application process.

Flutter Favorites project

The Flutter Ecosystem Committee held a meeting again and designated the following packages as Flutter Favorite packages:

使用 flex_color_scheme 构建的可灵活折叠的应用

Congratulations to the authors of these packages, and thank you for supporting the Flutter community through your hard work. If you are interested in nominating your favorite Flutter package for the Flutter Favorite award, please follow the guidelines and instructions on the Flutter Favorite program page

Platform-specific plugins

If you are a package/plugin author, you need to declare and implement which platforms are supported. If you're platform-native code plug-ins using a specific build, you can use pluginClass property project pubspec.yaml in
To achieve this, this attribute will specify the name of the native class that provides native functionality:

flutter:
  plugin:
    platforms:
      android:
        package: com.example.hello
        pluginClass: HelloPlugin
      ios:
        pluginClass: HelloPlugin

However, as Dart FFI becomes more mature, it is possible to use 100% Dart to implement platform-specific functions, just like path_provider_windows package does. In this case, you don't have any native classes to use, but you still want to specify your plugin to only support certain platforms. At this point you can use the dartPluginClass attribute instead:

flutter:
  plugin:
    implements: hello
    platforms:
      windows:
        dartPluginClass: HelloPluginWindows

After this setting, even if you don't have any native code, you can customize the plug-in for a specific platform. You must also provide the Dart plug-in class. For details, you can read the Dart platform implementation document Flutter document to learn more.

Firebase related updates

Another important component of the Flutter ecosystem is FlutterFire, which is used by about two-thirds of Flutter applications. This stable version adds a series of new features to facilitate developers to better use Firebase in Flutter:

Production quality

The FlutterFire plugins almost all been converted from a beta version to a stable version, which can be used in a production environment.

Android, iOS and the web version of the plug-in to stable version, including Analytics , Dynamic Links , an In-App Messaging , Performance Monitoring , Realtime Database , Remote Config and Installations . Some Firebase libraries themselves are still in beta on some platforms, so its Flutter plugin will also be in beta status, such as App Check on the macOS platform. But FlutterFire plug-ins like Realtime Database, Analytics, Remote Config, etc. are already available in the production environment, you can choose to give it a try!

Firebase initialization only needs to be configured in the Dart code

Because these package has reached production quality, and now you only in Dart code configuration , you can complete the Firebase initialized.

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());
}

The various configuration information defined in the firebase_options.dart file can be used to initialize Firebase in each supported platform of your choice:

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',
);

If you want to initialize a custom data structure for each platform, please use this flutterfire command line tool to complete:

This command line tool will find the unique bundle ID from the subfolders of each platform, and then use it to find and create matching Firebase project details under the specific platform. This means that you will save the time of downloading the .json file to the Android project and downloading the .plist file to the iOS and macOS projects. Of course, there is no need to copy and paste the code to your Web project. In other words, no matter which platform your app wants to initialize Firebase for, this code can do it for you. Of course, this may not be the only place to initialize the code, such as when you need to create Crashlytics debug symbols (dSYM) in Android or iOS. But at least it can run quickly for the new Firebase project.

Use Firebase in DartPad

Since we can only initialize and use FlutterFire in Dart code, DartPad naturally supports the use of Firebase:

Here is a demo of an online chat built using Flutter and Firebase, all of which can be used directly in DartPad without installing anything. DartPad's support for Firebase already includes core APIs, authentication and Firestore. As time progresses, DartPad will support more Firebase services in the future.

Another support is to embed the DartPad instance directly in the FlutterFire document, such as the Firestore sample page :

In this example, you will see the documentation of Cloud Firestore and sample application , which can be run and edited directly in the browser without installing any software.

Firebase user interface

Most users have an identity verification process, including but not limited to login via email and password or a third-party account. Using the Firebase Authentication service, you can complete functions such as creating new users, email authentication, resetting passwords, even SMS two-step verification, logging in with a mobile phone number, and combining multiple accounts into one account. Until today, developers still need to complete these logic and UI by themselves.

Today we hope you all try a new package named flutterfire_ui . This package can build a basic authentication experience with a small amount of code. For example, the Firebase project is set to log in with an email and Google account:

With this configuration, you can construct an authentication with the following code:

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
        },
      );
}

This code will first initialize Firebase, and then it will find that the user has not logged in and display the login interface. The SigninScreen widget is configured with email and Google account login. The code also uses the firebase_auth package to monitor the user’s authentication status. Therefore, once the user has logged in, You can display the next application content. Using this code snippet, you will be able to complete the authentication function on all platforms supported by Firebase.

If you add some other configurations, you can also add some images and custom text (see this document details) to provide you with a more comprehensive user authentication experience:

The screenshot above is the identity authentication of the mobile terminal, but because flutterfire_ui is responsive, it will look like this on a desktop browser:

Users can log in directly with their email address and password. If they choose to log in with Google ID verification, whether on mobile, web or desktop, they will see the common Google ID verification process. If the user does not have an account yet, they can click the register button to enter the registration process. After the user logs in, there will be email verification, password reset, logout, and social account binding functions. Authentication via email and password is applicable to all platforms, and supports login with Google, Facebook and Twitter accounts, as well as login via Apple ID on the iOS system. flutterfire_ui supports a variety of scenarios and navigation schemes, as well as customization and localization options. See the FlutterFire UI document learn more.

In addition, identity authentication is not the only Flutter UI related function supported by flutterfire_ui It can also show users an infinite scrolling data list from Firebase data query. This version also includes a FirestoreListView can be used:

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(),
              ],
            );
          },
        ),
      );
}

The actual operating effects are as follows:

Or if you want to provide users with the function of FirestoreDataTable table data, you can use 061bac0de5c654:

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'),
      },
    );
  }
}

The effect is this:

About authentication, list view and more information about data tables, consult the documentation flutterfire_ui . This package is still in preview mode, you may add more new features, if you have any questions, or to use a new feature requests, please in GitHub repo participate in our discussions .

Firestore Object/Document Mapping (ODM)

We also released the Firestore Object/Document Mapping (ODM) . The goal of Firestore ODM is to allow developers to more efficiently simplify the use of Firestore through type safety, structured objects and methods. By generating code, you can model data in a type-safe manner, thereby improving the syntax for interacting with documents and collections:

@JsonSerializable()
class Person {
  Person({required this.name, required this.age});

  final String name;
  final int age;
}

@Collection<Person>(‘/persons’)
final personsRef = PersonCollectionReference();

With these types, you can perform type-safe queries:

personsRef.whereName(isEqualTo: 'Bob');
personsRef.whereAge(isGreaterThan: 42);

ODM also supports strongly typed sub-collections. It also provides some built-in and optimized widgets to rebuild its select function. You can read about Firestore ODM document Because this is still Alpha version, as to us in the GitHub repo feedback .

Desktop platform update

Flutter 2.8 version has taken another big step on the road to stable versions of Windows, macOS and Linux.
Our goal is high quality standards, including internationalization and localization support, such as new Chinese input method support , Korean input method support and just merged Kanji (Japanese) IME support. Or, just like we are closely building Windows accessibility support .
For Flutter, it is not enough to "run" on the desktop of the stable channel. It must run well on devices with different abilities and languages and cultures around the world. We have not reached the goal we want, but the future can be expected!

One example is that we refactored Flutter's architecture to handle keyboard events to allow synchronous responses. This enables the widget to handle the key press and intercept its passing through the rest of the entire widget tree. We completed this work in Flutter 2.5 and fixed many problems in Flutter 2.8. This is a redesign of how we handle device-specific keyboard input, and the continuous work of refactoring Flutter's way of handling text editing, all of which are necessary for input-intensive desktop applications such as keyboards.

In addition, we are continuing to Flutter to extend the definition of visual density , exposing the dialog alignment settings so that developers can achieve a more friendly desktop UI.

Finally, the Flutter team is not the only team working hard for Flutter desktop. For example, Canonical's desktop team is working with Invertase to develop the most popular Flutter Firebase plugin on Linux and Windows.

You can read more about the preview version Invertase blog at

DartPad

If there is no tool improvement, then the release of this new version of Flutter is incomplete. We will focus on the improvements of DartPad, the biggest of which is the support for more software packages. In fact, there are currently 23 packages available for import. In addition to several Firebase services, the list also includes popular packages bloc , characters , collection , google_fonts and flutter_riverpod
The DartPad team will continue to add new packages. If you want to see which packages are currently supported, you can click the information icon in the lower right corner.

If you want to know about our plans to add new packages to DartPad in the future, please check this article Dart wiki.
There is another new DartPad feature that is also very convenient. Before that, DartPad always runs with the latest stable version. In the new version, you can use the new Channel menu status bar to switch to using the latest Beta channel version and the previous stable version (we call it "old channel" old channel).

The usage scenarios of the old channels in DartPad, for example, you are writing a blog post, and the latest stable version is still very popular, then this will be very useful.

Remove Dev channel

Flutter's release "channel" (that is, channel) determines the speed at which the Flutter framework and engine change on your development machine. stable represents the least changes, and master represents the most. Due to limited resources, we decided to stop updating the dev channel recently. Although we did receive some questions about the dev channel, we found that less than 3% of Flutter developers use the dev channel. Therefore, we decided that will officially deactivate the dev channel .

Because although few developers use the dev channel, Flutter engineers still need to spend a lot of time and energy to maintain it.
If you basically only use stable channel (more than 90% of Flutter people are doing this), then this change will not affect your daily development. By giving up maintaining this channel, developers can also make one less channel selection decision, and the Flutter team can also spend time and energy on other things. You can use the flutter channel command to decide which channel you want. The following is the plan of the Flutter team for each channel:

dev channel in the next few months, please consider using the beta or master channel, depending on your tolerance for changes and the balance between using the "newest" or "best".

Breaking changes

As always, we strive to reduce the number of breaking changes in each version. In this version, Flutter 2.8 has no major changes except for the deprecated API that disruptive change policy

  • 90292 Remove the obsolete autovalidate
  • 90293 remove the obsolete FloatingHeaderSnapConfiguration.vsync
  • 90294 remove the obsolete AndroidViewController.id
  • 90295 remove the obsolete BottomNavigationBarItem.title
  • 90296 remove the obsolete text input formatting class

If you are still using the API and want to learn how to migrate code that you can read Migration Guide documents on Flutter website .
As always, thank you very much for the test case for helping us identify these breaking changes.

Summarize

As we end 2021 and look forward to 2022, the Flutter team would like to thank the entire Flutter community for their work and support. It is true that we are building Flutter for more and more developers in the world, but without you and every developer, we cannot maintain and build it. The Flutter community is different, thank you for everything!


Flutter
350 声望2.5k 粉丝

Flutter 为应用开发带来了革新: 只要一套代码库,即可构建、测试和发布适用于移动、Web、桌面和嵌入式平台的精美应用。Flutter 中文开发者网站 flutter.cn