如何调试flutter应用
The Dart Analyzer
这个工具帮助你分析代码,发现可能的错误。
运行命令行
终端进入flutter工程所在目录,执行flutter analyze
使用IntelliJ IDEA

Dart Observatory
dart语句级单步调试器和分析器
运行命令行
终端进入flutter工程所在目录,执行flutter run命令运行app,运行的时候,在控制台可以看到一个Observatory URL(如http://127.0.0.1:8100/),我们可以通过浏览器打开,直接用语句级的单步调试程序连接到你的应用程序。
使用IntelliJ IDEA
IDE内置调试器,运行的时候选择debug按钮
debugger()
使用debugger()语句插入编程式断点,调用这个方法需要import 'dart:developer'。该debugger()语句带有一个可选when参数,您可以指定该参数仅在特定条件为真时中断,如下所示:
void someFunction(double offset) {
debugger(when: offset > 30.0);
// ...
}
使用print()方法打印日志到控制台
我们可以使用flutter logs来查阅日志,这个命令基本上是对adb logcat 命令做了一层封装。
如果打印日志过多,Android的做法是设置日志优先级或者有时会丢弃一些日志行。为了避免这种情况,我们可以使用debugPrint()方法,这个方法是对print()方法做了一层包装,将输出限制在一个级别,避免被Android内核丢弃。
flutter框架中的许多类都有有用的toString实现。按照惯例,这些输出通常包括runtimeType对象的一行,通常在ClassName表格中。树中使用的某些类也具有从那一点返回整个子树的多行描述的toStringDeep方法。有些详细实现了toString方法的类,有一个相应的只返回类型或者对对象只有一两个词语简短描述的toStringShort方法。
调试模式断言
在开发过程中,强烈建议您使用Flutter的“调试”模式,有时也称为“检查”模式。如果你使用flutter run命令,调试模式是默认的。在这种模式下,Dart assert语句被启用,Flutter框架使用它来执行许多运行时检查,验证赋值是否合法。
当一个赋值不合法时,它会向控制台报告,并提供一些上下文信息来帮助追踪问题的根
import 'package:flutter/material.dart';
void main() {
runApp(
new MaterialApp(
home: new AppHome(),
),
);
}
class AppHome extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Material(
child: new Center(
child: new FlatButton(
onPressed: () {
debugDumpApp();
},
child: new Text('Dump App'),
),
),
);
}
}
源。
要关闭调试模式并使用发布模式,请使用flutter run --release运行您的应用程序,这也关闭了Observatory调试器。我们也可用--profile替代--release, 一种关闭除了Observatory调试器之外的所有辅助工具的中间模式,也称为“分析模式”。
转储应用程序状态
Flutter框架的每一层都提供了将其当前状态转储到控制台(使用debugPrint)的功能。
控件层
我们可以使用debugDumpApp()转储Widgets库的状态,示例:
import 'package:flutter/material.dart';
void main() {
runApp(
new MaterialApp(
home: new AppHome(),
),
);
}
class AppHome extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Material(
child: new Center(
child: new FlatButton(
onPressed: () {
debugDumpApp();
},
child: new Text('Dump App'),
),
),
);
}
}
控制台会输出一个“扁平化”的树,显示了通过各种build函数创建的所有控件。

渲染层
如果您尝试调试布局问题,那么控件层的树可能不够详细。在这种情况下,您可以通过调用debugDumpRenderTree()转储渲染树 。和debugDumpApp()用法一样,除了布局或绘画阶段之外,您可以随时调用它。约定俗成,我们最好在帧回调 或事件处理时调用它。
要调用debugDumpRenderTree(),我们需要import 'package:flutter/rendering.dart';
上面示例调用debugDumpRenderTree(),输出结果如下所示:
渲染层
如果您尝试调试布局问题,那么控件层的树可能不够详细。在这种情况下,您可以通过调用debugDumpRenderTree()转储渲染树 。和debugDumpApp()用法一样,除了布局或绘画阶段之外,您可以随时调用它。约定俗成,我们最好在帧回调 或事件处理时调用它。
要调用debugDumpRenderTree(),我们需要import 'package:flutter/rendering.dart';
上面示例调用debugDumpRenderTree(),输出结果如下所示:

图层
如果您正在尝试调试混合问题,则可以使用 debugDumpLayerTree()。对于上面的例子,它会输出:

这是在根图层对象上调用toStringDeep的输出。
根的变换是应用设备像素比的变换;在本例中,每个逻辑像素的比率为3.5个设备像素。
RepaintBoundary控件在渲染层中创建了一个新的图层RenderRepaintBoundary,通常用来减少需要重新绘制的层数。
语义
您还可以使用debugDumpSemanticsTree()获得语义树(该树存在于系统可访问的api中)的转储。要使用这个功能,您必须首先设置允许访问,例如,通过启用系统可访问性工具或SemanticsDebugger。
上面的例子调用debugDumpSemanticsTree(),控制台将会输出下面结果:
https://img-blog.csdn.net/20171227193605109?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvam9obldjaGV1bmc=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast
可视化调试
你还可以通过设置debugPaintSizeEnabled为true来更直观的调试布局问题,这是渲染库中的一个布尔变量,当该变量为true时,它可以随时生效,并且影响所有地方的绘制。最简单的办法是在void main()主函数顶部入口去设置它。
当我们打开可视化调试时,所有子控件内边距会有一个明亮渐变的深蓝色边框,控件中间显示一个黄色箭头,控件间距会显示灰色。
debugPaintBaselinesEnabled的功能类似于对象的基准线,字母基线显示亮绿色,表意基线显示橙色。
debugPaintPointersEnabled标志位会打开一种特殊模式,让所有的对象都突出显示,这个可以帮助你发现哪一个对象不能正确的进行测试,比如,某个对象在其父类的范围之外,就不会第一时间被考虑进行命中测试。
如果您尝试调试混合图层,例如,确定是否以及在何处添加RepaintBoundary控件,可以使用debugPaintLayerBordersEnabled标志位,它使用橙色来绘制每个图层的边界,或者用debugRepaintRainbowEnabled标志位,当图层重新绘制时,它将让图层显示旋转的色彩。
所有这些标志位只在调试模式下工作。一般来说,在Flutter框架中,任何以“debug…”开头的变量或方法,都只能在调试模式下有效。
调试动画
调试动画最简单的方法是减慢它们的速度。为此,将timeDilation变量(在scheduler库中)设置为大于1.0的数字,例如50.0。最好在应用程序启动时只设置一次。如果您在运行中更改它,尤其是在动画运行时将其值变小,则框架可能会观察到时间倒退,这可能会导致断言,并且通常会影响效果。
调试性能问题
要知道导致你应用程序重新布局或重新绘制的原因,您可以分别设置 debugPrintMarkNeedsLayoutStacks 和 debugPrintMarkNeedsPaintStacks标志。
每当渲染框被要求重新布局和重新绘制时,都会随时将堆栈跟踪日志打印到控制台。如果这种方法对你有用,你可以使用services库中的debugPrintStack()方法按需打印自己的堆栈跟踪日志。
测试应用程序启动时间
要收集有关Flutter应用程序启动所需时间的详细信息,可以执行如下命令:
$ flutter run --trace-startup --profile
跟踪日志被保存在你的Flutter工程build目录下一个叫start_up_info.json的json文件里。日志会列出从应用启动到这些以微秒捕获的跟踪事件所用的时间:
进入Flutter引擎代码的时间
绘制应用第一帧的时间
初始化Flutter框架的时间
完成Flutter框架初始化的时间
例如:
{
"engineEnterTimestampMicros": ,
"timeToFirstFrameMicros": ,
"timeToFrameworkInitMicros": ,
"timeAfterFrameworkInitMicros":
}
跟踪任何Dart代码的性能
要执行自定义性能跟踪,去测量dart任一代码块的
CPU时间和墙上时钟时间,实现类似Android性能分析工具systrace的功能,我们可以使用dart:developer里面的时间轴工具来包装你想测试的代码:
Timeline.startSync('interesting function');
// iWonderHowLongThisTakes();
Timeline.finishSync();
然后打开应用分析器的时间轴页面,检查dart记录选项并执行你想测试的功能。
刷新该页面,将会在Chrome浏览器的跟踪工具中按时间顺序显示应用程序的时间轴记录。
务必使用flutter run --profile命令运行应用程序,以保证运行时性能特征与最终产品的性能紧密匹配。
性能覆盖图
要获得应用程序性能的图形视图, 我们需要将MaterialApp构造函数的showPerformanceOverlay参数设为true, WidgetsApp构造函数也有类似的参数。 如果你没有使用MaterialApp或者WidgetsApp, 你可以将你的应用程序封装在一个堆栈中,调用new PerformanceOverlay.allEnabled()方法创建一个控件放在堆栈上。
这将显示两个图表:上面是GPU线程花费的时间,下面是CPU线程花费的时间。图中的白线沿垂直轴显示16ms的增量;如果图表经过其中的一条白线,那么你运行速度在60Hz以下,横轴代表框架。图表只会在应用程序绘制时更新,所以如果处于空闲状态,图表将停止移动。
这个操作一定是在发布模式下完成,因为在调试模式下,会故意牺牲性能来换取旨在辅助开发的昂贵的断言,这样结果将是误导性的。
Material网格
当我们开发实现Material design的应用时,应用上会覆盖一个帮助验证对齐的Material Design基线网格。 为此,在调试模式下,将MaterialApp构造函数的debugShowGrid参数设为true,将会覆盖这样一个网格。
你也可以直接使用GridPaper控件在非Material应用程序上覆盖这样的网格。
如何调试flutter应用的更多相关文章
- Vscode 调试 Flutter 项目
1.Vscode 中打开 flutter 项目进行开发 2.运行 Flutter 项目 flutter run r 键:点击后热加载,也就算是重新加载吧. p 键:显示网格,这个可以很好的掌握布局情况 ...
- VSCode调试Flutter的问题解决
错误:Target of URI doesn't exist: package:fultter/material.dart 原因:flutter版本不匹配.flutter升级到了最新版本,而项目引用的 ...
- 使用VS Code调试Flutter(检查用户页面)
官方提供的是Flutter Widget Inspector,详见https://flutterchina.club/inspector/ 我用的是另外一种好用的调试工具 Dart DevTools ...
- Flutter upgrade更新版本引发的无法启动调试APP的错误 target:kernel_snapshot failed”
前言 我的主机上的Flutter 本地的分支是在 beta,因为去年想尝鲜Flutter Web,所以一直没切回来stable分支. 早上打开VSCode,右下角弹出了Flutter upgrade的 ...
- 《Flutter实战》开源电子书
<Flutter实战>开源电子书 <Flutter实战> 开源了,本书为 Flutter中文网开源电子书项目,本书系统介绍了Flutter技术的各个方面,本书属于原创书籍(并非 ...
- Flutter系列博文链接
Flutter系列博文链接 ↓: Flutter基础篇: Flutter基础篇(1)-- 跨平台开发框架和工具集锦 Flutter基础篇(2)-- 老司机用一篇博客带你快速熟悉Dart语法 Flutt ...
- 深入理解 Flutter 的编译原理与优化
阿里妹导读:对于开发者而言,Flutter工程和我们的Android/iOS工程有何差别?Flutter的渲染和事件传递机制如何工作?构建缓慢或出错又如何去定位,修改和生效呢?凡此种种,都需要对Flu ...
- Flutter汇总贴
Fluuter常遇到的问题 Flutter从入门到进阶实战携程网App_汇总贴 Flutter教程网 http://www.flutterj.com/ 第三季:https://jspang.com/p ...
- Flutter走过的坑(持续更新)
1 Target of URI doesn't exist 'package:flutter/material.dart' 官方下载的flutter中有一个example文件夹,里面有很多flutte ...
随机推荐
- (转)python字符串函数
原文:https://www.cnblogs.com/emanlee/p/3616755.html https://blog.csdn.net/luoyhang003/article/details/ ...
- linux一键安装php环境
1.下载一键安装包: http://pan.baidu.com/s/1o6lWyeu 2.unzip -x sh.zip chmod -R 755 sh ./install.sh 等待半小时左右 3. ...
- 【原】Ubuntu13.04安装、卸载Gnome3.8
添加 GNOME 3 PPA(Personal Package Archives) 我们先给Ubuntu的Software Sources增加GNOME 3 PPA.这可以不用命令行就做到,但出于简单 ...
- 5-niginx-健康检查模块
1, nginx有一个自带的健康检查模块, 过于丑陋... 只需要在 nginx.conf下的http中的server配置如下即可 location /basic_status { stub_sta ...
- BSDL
BSDL(边界扫描描述语言)文件是使用边界扫描进行电路板级和系统级测试与在系统编程所必需的. BSDL 文件是描述一个 IC 中的 IEEE 1149.1 或 JTAG 设计电子数据表,这些文件由 I ...
- 修改MVC默认的pageBaseType以添加功能
试想下在MVC的前端页面JS或者html中需要使用多语言,而后端的多语言是维护在资源文件中的,前端如果使用的话需要使用AJAX频繁的获取,一个页面中可能会存在大量的需要语言转换的地方,频繁使用AJAX ...
- Socket编程 - 网络基础知识
API编程部分:http://www.cnblogs.com/Jimmy1988/p/7895213.html 1. 协议简介 此处,我们主要介绍Linux编程常用的三种协议(TCP/UDP/IP), ...
- springboots 配置文件
1.build.gradle buildscript { // 声明变量 ext { springBootVersion = '1.5.2.RELEASE' } // 仓库 repositories ...
- SQL运算符
SQL运算符实例代码教程 - 运算符是一个保留字或字符,主要用于在SQL语句的WHERE子句来执行,比较和算术运算等操作. http://www.yiibai.com/sql/sql_operato ...
- 用fullPage来实现全屏滚动效果
[注意]所有的page要用div包裹,id为fullpage.不能直接包在body中 [使用fullpage的步骤] 1.导入 JQuery.js,fullpage.js,fullpage.css ...