Flutter) 应用在热重载前不会处理

问题描述

我现在学习颤振。但是我遇到了一个关于 dispose 的问题。

首先我看到你我的代码。看起来很长,但代码并不难。

ma​​in.dart

import 'package:Flutter/material.dart';

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

class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: FirstScreen(),);
  }
}

class FirstScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        // After hot reload,title will be changed to 'First Screen (After Hot Reload)'
        title: Text('First Screen (Before Hot Reload)',style: TextStyle(fontWeight: FontWeight.bold)),),body: SafeArea(
        child: Center(
          child: ElevatedButton(
            onpressed: () {
              Navigator.push(context,MaterialPageRoute(builder: (_) => SecondScreen()));
            },child: Text('Go To Second Screen',style: TextStyle(fontWeight: FontWeight.bold,fontSize: 24)),);
  }
}


class SecondScreen extends StatefulWidget {

  @override
  _SecondScreenState createState() => _SecondScreenState();
}

class _SecondScreenState extends State<SecondScreen> with TickerProviderStateMixin {
  List<ScrollController> scrollControllers;
  List<AnimationController> animationControllers;
  List<FocusNode> focusNodes;

  @override
  void initState() {
    super.initState();
    scrollControllers = List.generate(10000,(_) => ScrollController());
    animationControllers = List.generate(10000,(_) => AnimationController(vsync: this,duration: Duration(microseconds: 300)));
    focusNodes = List.generate(10000,(_) => FocusNode());
  }

  @override
  void dispose() {
    scrollControllers.forEach((element) { element.dispose();});
    animationControllers.forEach((element) { element.dispose();});
    focusNodes.forEach((element) { element.dispose();});
    print('No Get with dispose');
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        // After hot reload,title will be changed to 'Second Screen (After Hot Reload)'
        title: Text('Second Screen (Before Hot Reload)',body: SafeArea(
        child: Center(child: Text('Second Screen')),);
  }
}

我构建了这段代码并观察了这个简单应用程序的内存使用情况。

My app memory usage

我通过这一步运行这个应用程序。

  1. 我以调试模式运行应用。
  2. 我转到第二个屏幕。 (然后,此应用将在 initState() 方法中创建 10,000 个 ScrollControllerAnimationControllerFocusNode
  3. 我回到第一个屏幕。 (我认为这个应用程序应该在 dispose() 方法中处理 ScrollControllerAnimationControllerFocusNode。但它没有。)
  4. 我对代码的改动很小。只是 AppBar 的标题文本。并重新加载。然后,与应用开始时类似,内存使用情况发生了变化。
  5. 我转到第二个屏幕。它会创建类似于第 2 步的内容
  6. 我回到第一个屏幕。此时,它正确处理。

问题 这是我的问题。为什么这个应用程序没有在第 3 步处理 scrollControllersanimationConrollersfocusNodes?但是,在热重载后,当它返回到第一个屏幕(第 6 步)时,该应用程序会正确处理。这对我来说很奇怪。为什么一开始build app没有处理,但是hot reload app后处理正确?


ps) 我使用 IntelliJ。

'Flutter --version' 结果

Flutter 1.22.5 • channel stable • https://github.com/Flutter/Flutter.git
Framework • revision 7891006299 (7 weeks ago) • 2020-12-10 11:54:40 -0800
Engine • revision ae90085a84
Tools • Dart 2.10.4

'Flutter doctor'结果

Doctor summary (to see all details,run Flutter doctor -v):
[✓] Flutter (Channel stable,1.22.5,on Microsoft Windows [Version 10.0.19042.746],locale ko-KR)
[!] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
    ✗ Android license status unkNown.
      Run `Flutter doctor --android-licenses` to accept the SDK licenses.
      See https://Flutter.dev/docs/get-started/install/windows#android-setup for more details.
[!] Android Studio (not installed)
[!] VS Code (version 1.52.1)
    ✗ Flutter extension not installed; install from
      https://marketplace.visualstudio.com/items?itemName=Dart-Code.Flutter
[✓] Connected device (1 available)

解决方法

如果您的任务需要在热重载时进行特殊处理,您可以提供一个 reassemble 钩子(类似于 dispose)来运行您需要的代码:

// in your State widget:

@override
void reassemble {
  debugPrint('Captain,we are going down!!!');
  super.reassemble(); // must call
}

https://api.flutter.dev/flutter/widgets/State/reassemble.html 查看更多。 文档说这仅适用于调试版本,因为当然,您不会在生产版本上热重载。 :)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...