Hot reload

640?wx_fmt=jpeg

Flutter's hot reload feature helps you quickly and easily test, build user interfaces, add features, and fix errors without restarting the application. Hot reload is achieved by injecting updated source code files into the running Dart virtual machine (VM). After the virtual machine updates the class with the new fields and functions, the Flutter framework will automatically rebuild the widget tree so that you can quickly see the effect of the changes.

To hot reload the Flutter application:

(2) Modify a Dart file in the project. Most types of code changes can be hot reloaded; for a list of changes that require restarting the application, see Limitations.

(3) If you are working in an IDE/editor that supports Flutter IDE tools, please select Save All ( cmd-s/ ctrl-s), or click the Hot Reload button on the toolbar.

If you are using the command line to  flutter run run the application, enter it in a terminal window  r.

After successfully executing the hot reload, you will see a message similar to the following in the console:

Performing hot reload...
Reloaded 1 of 448 libraries in 978ms.
The application is updated to reflect your changes, and the current state of the application (the value of the counter variable in the example above) will remain. Your application will continue to execute from where the hot reload command was previously run. The code is updated and execution continues.
Only when the modified Dart code is run again, the code changes will have a visible effect. Specifically, hot reloading will cause all existing widgets to be rebuilt. Only the code related to the rebuild of widgets will be automatically re-executed.
The next section will introduce the common situations where the modified code will not run again after hot reload. In some cases, small changes to the Dart code will ensure that you can continue to use hot reloading.
1. Compilation error
When code changes cause compilation errors, hot reloading generates an error message similar to the following:
Hot reload was rejected:
'/Users/obiwan/Library/Developer/CoreSimulator/Devices/AC94F0FF-16F7-46C8-B4BF-218B73C547AC/data/Containers/Data/Application/4F72B076-42AD-44A4-A7CF-57D9F93E895E/tmp/ios_testWIDYdS/ios_test/lib/main.dart': warning: line 16 pos 38: unbalanced '{' opens here
  Widget build(BuildContext context) {
                                     ^
'/Users/obiwan/Library/Developer/CoreSimulator/Devices/AC94F0FF-16F7-46C8-B4BF-218B73C547AC/data/Containers/Data/Application/4F72B076-42AD-44A4-A7CF-57D9F93E895E/tmp/ios_testWIDYdS/ios_test/lib/main.dart': error: line 33 pos 5: unbalanced ')'
    );
    ^
In this case, you only need to correct the error of the above code, and you can continue to use hot reload.
2. The previous state and the new code coexist
Flutter's hot reload feature (sometimes called stateful hot reload) preserves the state of your application. This design allows you to view the effects of recent changes without discarding the current state. For example, if your application requires a user to log in, you can modify and reload the page several levels down in the navigation hierarchy without having to re-enter the login credentials. The state remains unchanged, which is usually the desired behavior.
If the code change affects the state of the application (or its dependencies), the data used by the application may not be exactly the same as the data it executes from the beginning. After hot reload and complete restart, the result may be different behavior.
For example, if you change the definition of a class from StatelessWidget to StatefulWidget (or vice versa), the previous state of the application will remain after hot reloading. However, the status may not be compatible with the new changes.
Refer to the following code:
class MyWidget extends StatelessWidget {
  Widget build(BuildContext context) {
    return GestureDetector(onTap: () => print('T'));
  }
}
After running the application, if you make the following changes:
class MyWidget extends StatefulWidget {
  @override
  State<MyWidget> createState() => MyWidgetState();
}

class MyWidgetState extends State<MyWidget> { /*...*/ }
After hot reload; the console will display an assertion failure message similar to the following:
MyWidget is not a subtype of StatelessWidget
In these cases, a complete restart is required to view the updated application.
3. The code has changed but the state of the application has not changed
In Dart, static fields are initialized lazily. This means that when the Flutter application is run for the first time and a static field is read, the value of the static field will be set to the result of its initial expression. Both global variables and static fields are considered state, so they will not be reinitialized during hot reload.
If you change the initialization statements for global variables and static fields, you need to fully restart to see the changes. For example, refer to the following code:
final sampleTable = [
  Table("T1"),
  Table("T2"),
  Table("T3"),
  Table("T4"),
];
After running the application, if you make the following changes:
final sampleTable = [
  Table("T1"),
  Table("T2"),
  Table("T3"),
  Table("T10"),    // modified
];
After hot reload, this change has no effect.
Instead, in the following example:
const foo = 1;
final bar = foo;
void onClick() {
  print(foo);
  print(bar);
}
The first time you run the application, it will print  1  and  1 . Then, if you make the following changes:
const foo = 2;    // modified
final bar = foo;
void onClick() {
  print(foo);
  print(bar);
}
After hot reload, the 2 sum  is now printed out  1 . Although the changes to the field value defined by const will always be reloaded, the initialization statement of the static field will not be rerun. Conceptually, const fields are considered aliases rather than state.
The Dart VM detects initialization program changes and flags when a set of changes need to be fully restarted to take effect. In the above example, most of the initialization work will trigger the marking mechanism, but it does not apply to the following situations:
final bar = foo;
In order to be able to change  foo  and view the changes after hot reloading, the field should be redefined with const or getter to return the value instead of final. E.g:
const bar = foo;
or:
get bar => foo;
Learn more about the difference between the const and final keywords in Dart.
4. The user interface has not changed
Even though the hot reload operation appears to succeed and no exception is thrown, some code changes may not be visible in the updated UI. This behavior main()  is common after changing the method of the application  .
As a general rule, if the modified code is downstream of the root widget's build method, hot reloading will work as expected. However, if the modified code will not be re-executed by rebuilding the widget tree, you will not see its effect after hot reloading.
For example, refer to the following code:
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  Widget build(BuildContext context) {
    return GestureDetector(onTap: () => print('tapped'));
  }
}
After running the application, you may change the code like the following example:
import 'package:flutter/widgets.dart';

void main() {
  runApp(const Center(
      child: const Text('Hello', textDirection: TextDirection.ltr)));
}
After a complete restart, the program will execute the new main()  method from the beginning  and build a widget tree to display text  Hello .
However, if you run through hot reloading after the change, the main()  method will not be re-executed, and the unmodified MyApp  instance will be used  as the root widget tree to build a new widget tree. The result will not change after hot reloading.
However, if you hot reload the application after this change, main() will not be re-executed and the widget tree will be rebuilt using the unchanged instance of MyApp as the root widget. The result did not change significantly after hot reload.
5. Restrictions
You may also encounter rare cases where hot reloading is not supported at all. These include:
  • Changing the  initState() method will not produce any effect after hot reloading, and it needs to be restarted.

  • The enumeration type is changed to a general class or the general class is changed to an enumeration type. For example, if you change:

enum Color {
  red,
  green,
  blue
}
To:
class Color {
  Color(this.i, this.j);
  final int i;
  final int j;
  }
  • The generic class declaration was modified. For example, if you change:
class A<T> {
  T i;
}
To:
class A<T, V> {
  T i;
  V v;
}
In these cases, hot reload will generate a diagnostic message, will fail, and will not commit any changes.
6. How to achieve
When calling hot reload, the host will view the edited code since the last compilation. Recompile the following files:
  • Any files with code changes;
  • The main entry file of the application.
  • Files affected by the main entry file.
In Dart 2, the Dart source code of these files is converted into core files and sent to the Dart VM of the mobile device.
Dart VM reloads all files in the new kernel file. So far, no code has been re-executed.
Then, the hot reload mechanism causes the Flutter framework to trigger the reconstruction/relayout/redraw of all existing widgets and rendered objects.

640?wx_fmt=png

Guess you like

Origin blog.csdn.net/weixin_43459071/article/details/102927829