热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

flutter泛型_Flutter中文文档:热重载(Hotreload)

热重载Flutter的热重载功能可帮助您在无需重新启动应用程序的情况下快速、轻松地测试、构建用户界面、添加功能以及修复错误。通过将更新的源代码文件注入到正在运行的Dart虚拟机(V
1b974144a52e96dce03811d8f7a13090.png

热重载

Flutter 的热重载功能可帮助您在无需重新启动应用程序的情况下快速、轻松地测试、构建用户界面、添加功能以及修复错误。通过将更新的源代码文件注入到正在运行的 Dart 虚拟机(VM)来实现热重载。在虚拟机使用新的字段和函数更新类之后, Flutter 框架会自动重新构建 widget 树,以便您可以快速查看更改的效果。

要热重载 Flutter 应用程序:

(1)在支持 Flutter 编辑器 或终端窗口运行应用程序,物理机或虚拟器都可以。 Flutter 应用程序只有在调试模式下才能被热重载。

(2)修改项目中的一个Dart文件。大多数类型的代码更改可以热重载;一些需要重新启动应用程序的更改列表,请参阅 限制。

(3)如果您在支持 Flutter IDE 工具的 IDE /编辑器中工作,请选择 Save All (cmd-s/ctrl-s),或单击工具栏上的 Hot Reload 按钮。

如果您正在使用命令行 flutter run 运行应用程序,请在终端窗口输入 r。

成功执行热重载后,您将在控制台中看到类似于以下内容的消息:

Performing hot reload...Reloaded 1 of 448 libraries in 978ms.

应用程序更新以反映您的更改,并且应用程序的当前状态(上面示例中的计数器变量的值)将保留。您的应用程序将继续从之前运行热重载命令的位置开始执行。代码被更新并继续执行。

只有修改后的 Dart 代码再次运行时,代码更改才会产生可见效果。具体来说,热重载会导致所有现有的 widgets 重新构建。只有与 widgets 重新构建相关的代码才会自动重新执行。

接下来的部分将介绍修改后的代码在热重载后不会再次运行的常见情况。在某些情况下,对 Dart 代码的小改动将确保您能够继续使用热重载。

1. 编译错误

当代码更改导致编译错误时,热重载会生成类似于以下内容的错误消息:

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

在这种情况下,只需更正上述代码的错误,即可以继续使用热重载。

2. 先前的状态与新代码并存

Flutter 的热重载功能(有时称为有状态热重载)可保留您的应用程序的状态。这种设计允许您能查看最近更改的效果,并且不会丢弃当前状态。例如,如果您的应用需要用户登录,您可以在导航层次结构中下几个级别修改并重新加载页面,而无需重新输入登录凭据。状态保持不变,这通常是期望的行为。

如果代码更改会影响应用程序(或其依赖项)的状态,则应用程序使用的数据可能与它从头开始执行的数据不完全一致。在热重载和完全重启之后,结果可能是不同的行为。

例如,如果您将某个类的定义从 StatelessWidget 改为 StatefulWidget(或反向更改),则在热重载之后,应用程序的以前状态将保留。但是,该状态可能与新的更改不兼容。

参考以下代码:

class MyWidget extends StatelessWidget { Widget build(BuildContext context) { return GestureDetector(onTap: () => print('T')); }}

运行应用程序后,如果进行以下更改:

class MyWidget extends StatefulWidget { @override State createState() => MyWidgetState();}class MyWidgetState extends State { /*...*/ }

热重载后;控制台将显示类似于以下内容的断言失败的信息:

MyWidget is not a subtype of StatelessWidget

在这些情况下,需要完全重新启动才可以查看更新后的应用程序。

3. 代码发生更改但应用程序的状态没有改变

在 Dart 中,静态字段会被惰性初始化。这意味着第一次运行 Flutter 应用程序并读取静态字段时,会将静态字段的值设为其初始表达式的结果。全局变量和静态字段都被视为状态,因此在热重载期间不会重新初始化。

如果更改全局变量和静态字段的初始化语句,则需要完全重启以查看更改。例如,参考以下代码:

final sampleTable = [ Table("T1"), Table("T2"), Table("T3"), Table("T4"),];

运行应用程序后,如果进行以下更改:

final sampleTable = [ Table("T1"), Table("T2"), Table("T3"), Table("T10"), // modified];

热重载后,这个改变并没有产生效果。

相反,在下面示例中:

const foo = 1;final bar = foo;void onClick() { print(foo); print(bar);}

第一次运行应用程序会打印 1 和 1。然后,如果您进行以下更改:

const foo = 2; // modifiedfinal bar = foo;void onClick() { print(foo); print(bar);}

热重载后,现在打印出 2和 1。虽然对 const 定义的字段值的更改始终会重新加载,但不会重新运行静态字段的初始化语句。从概念上讲,const 字段被视为别名而不是状态。

Dart VM 在一组更改需要完全重启才能生效时,会检测初始化程序更改和标志。在上面的示例中,大部分初始化工作都会触发标记机制,但不适用于以下情况:

final bar = foo;

为了能够更改 foo 并在热重载后查看更改,应该将字段重新用 const 定义或使用 getter 来返回值,而不是使用 final。例如:

const bar = foo;

或者

get bar => foo;

了解更多 Dart 中关于 const 和 final 关键字的区别。

4. 用户界面没有改变

即使热重载操作看起来成功了并且没有抛出异常,但某些代码更改可能在更新的 UI 中不可见。这种行为在更改应用程序的 main() 方法后很常见。

作为一般规则,如果修改后的代码位于根 widget 的构建方法的下游,则热重载将按预期运行。但是,如果修改后的代码不会因重新构建 widget 树而重新执行的话,那么在热重载后您将看不到它的效果。

例如,参考以下代码:

import 'package:flutter/material.dart';void main() { runApp(MyApp());}class MyApp extends StatelessWidget { Widget build(BuildContext context) { return GestureDetector(onTap: () => print('tapped')); }}

运行应用程序后,你可能会像如下示例更改代码:

import 'package:flutter/widgets.dart';void main() { runApp(const Center( child: const Text('Hello', textDirection: TextDirection.ltr)));}

完全重启后,程序会从头开始执行新的 main() 方法,并构建一个 widget 树来显示文本 Hello。

但是,如果您在更改后是通过热重载运行,main() 方法则不会重新执行,并且会使用未修改的 MyApp 实例作为根 widget 树来构建新的 widget 树,热重载后结果没有变化。

但是,如果您在此更改后热重新加载应用程序,main()则不会重新执行,并且使用未更改的实例MyApp作为根小部件重建窗口小部件树。热重载后结果没有明显变化。

5. 限制

您可能还会遇到极少数根本不支持热重载的情况。这些包括:

  • 更改 initState() 方法,热重载后不会产生效果,需要重新启动。
  • 枚举类型更改为常规类或常规类更改为枚举类型。例如,如果您更改:

enum Color { red, green, blue}

改为:

class Color { Color(this.i, this.j); final int i; final int j; }

  • 泛型类声明被修改。例如,如果您更改:

class A { T i;}

改为:

class A { T i; V v;}

在这些情况下,热重载会生成诊断消息,并会失败,也不会提交任何改变。

6. 如何实现

调用热重载时,主机会查看自上次编译以来编辑的代码。重新编译以下文件:

  • 任何有代码更改的文件;
  • 应用程序的主入口文件。
  • 受主入口文件影响的文件。

在 Dart 2 中,这些文件的 Dart 源代码被转换为 内核文件 并发送到移动设备的 Dart VM。

Dart VM 重新加载新内核文件中的所有文件。到目前为止,没有重新执行代码。

然后,热重载机制使 Flutter 框架触发所有现有的 widgets 和渲染对象的重建/重新布局/重绘。



推荐阅读
  • Android 构建基础流程详解
    Android 构建基础流程详解 ... [详细]
  • 本文介绍了一种自定义的Android圆形进度条视图,支持在进度条上显示数字,并在圆心位置展示文字内容。通过自定义绘图和组件组合的方式实现,详细展示了自定义View的开发流程和关键技术点。示例代码和效果展示将在文章末尾提供。 ... [详细]
  • Spring框架中枚举参数的正确使用方法与技巧
    本文详细阐述了在Spring Boot框架中正确使用枚举参数的方法与技巧,旨在帮助开发者更高效地掌握和应用枚举类型的数据传递,适合对Spring Boot感兴趣的读者深入学习。 ... [详细]
  • 使用 ListView 浏览安卓系统中的回收站文件 ... [详细]
  • Python 程序转换为 EXE 文件:详细解析 .py 脚本打包成独立可执行文件的方法与技巧
    在开发了几个简单的爬虫 Python 程序后,我决定将其封装成独立的可执行文件以便于分发和使用。为了实现这一目标,首先需要解决的是如何将 Python 脚本转换为 EXE 文件。在这个过程中,我选择了 Qt 作为 GUI 框架,因为之前对此并不熟悉,希望通过这个项目进一步学习和掌握 Qt 的基本用法。本文将详细介绍从 .py 脚本到 EXE 文件的整个过程,包括所需工具、具体步骤以及常见问题的解决方案。 ... [详细]
  • 在处理 XML 数据时,如果需要解析 `` 标签的内容,可以采用 Pull 解析方法。Pull 解析是一种高效的 XML 解析方式,适用于流式数据处理。具体实现中,可以通过 Java 的 `XmlPullParser` 或其他类似的库来逐步读取和解析 XML 文档中的 `` 元素。这样不仅能够提高解析效率,还能减少内存占用。本文将详细介绍如何使用 Pull 解析方法来提取 `` 标签的内容,并提供一个示例代码,帮助开发者快速解决问题。 ... [详细]
  • 本文探讨了如何利用Java代码获取当前本地操作系统中正在运行的进程列表及其详细信息。通过引入必要的包和类,开发者可以轻松地实现这一功能,为系统监控和管理提供有力支持。示例代码展示了具体实现方法,适用于需要了解系统进程状态的开发人员。 ... [详细]
  • 使用Maven JAR插件将单个或多个文件及其依赖项合并为一个可引用的JAR包
    本文介绍了如何利用Maven中的maven-assembly-plugin插件将单个或多个Java文件及其依赖项打包成一个可引用的JAR文件。首先,需要创建一个新的Maven项目,并将待打包的Java文件复制到该项目中。通过配置maven-assembly-plugin,可以实现将所有文件及其依赖项合并为一个独立的JAR包,方便在其他项目中引用和使用。此外,该方法还支持自定义装配描述符,以满足不同场景下的需求。 ... [详细]
  • 在C#编程中,设计流畅的用户界面是一项重要的任务。本文分享了实现Fluent界面设计的技巧与方法,特别是通过编写领域特定语言(DSL)来简化字符串操作。我们探讨了如何在不使用`+`符号的情况下,通过方法链式调用来组合字符串,从而提高代码的可读性和维护性。文章还介绍了如何利用静态方法和扩展方法来实现这一目标,并提供了一些实用的示例代码。 ... [详细]
  • 在对WordPress Duplicator插件0.4.4版本的安全评估中,发现其存在跨站脚本(XSS)攻击漏洞。此漏洞可能被利用进行恶意操作,建议用户及时更新至最新版本以确保系统安全。测试方法仅限于安全研究和教学目的,使用时需自行承担风险。漏洞编号:HTB23162。 ... [详细]
  • 深入浅出 webpack 系列(二):实现 PostCSS 代码的编译与优化
    在前一篇文章中,我们探讨了如何通过基础配置使 Webpack 完成 ES6 代码的编译。本文将深入讲解如何利用 Webpack 实现 PostCSS 代码的编译与优化,包括配置相关插件和加载器,以提升开发效率和代码质量。我们将详细介绍每个步骤,并提供实用示例,帮助读者更好地理解和应用这些技术。 ... [详细]
  • 本指南介绍了如何在ASP.NET Web应用程序中利用C#和JavaScript实现基于指纹识别的登录系统。通过集成指纹识别技术,用户无需输入传统的登录ID即可完成身份验证,从而提升用户体验和安全性。我们将详细探讨如何配置和部署这一功能,确保系统的稳定性和可靠性。 ... [详细]
  • 在Android平台中,播放音频的采样率通常固定为44.1kHz,而录音的采样率则固定为8kHz。为了确保音频设备的正常工作,底层驱动必须预先设定这些固定的采样率。当上层应用提供的采样率与这些预设值不匹配时,需要通过重采样(resample)技术来调整采样率,以保证音频数据的正确处理和传输。本文将详细探讨FFMpeg在音频处理中的基础理论及重采样技术的应用。 ... [详细]
  • POJ 2482 星空中的星星:利用线段树与扫描线算法解决
    在《POJ 2482 星空中的星星》问题中,通过运用线段树和扫描线算法,可以高效地解决星星在窗口内的计数问题。该方法不仅能够快速处理大规模数据,还能确保时间复杂度的最优性,适用于各种复杂的星空模拟场景。 ... [详细]
  • 线程能否先以安全方式获取对象,再进行非安全发布? ... [详细]
author-avatar
徐大总统_584
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有