开发者社区> 黎燃> 正文

Flutter如何调试应用【Dart Observatory 】以及调试模式断言

简介: Flutter如何调试应用【Dart Observatory 】以及调试模式断言
+关注继续查看
福利推荐:阿里云、腾讯云、华为云等大品牌云产品全线2折优惠活动来袭,4核8G云服务器899元/3年,新老用户共享优惠,点击这里立即抢购>>>

@[toc]

Flutter如何调试应用

我们上面写了Flutter测试应用,这远远不够,这篇,我们来写一下Flutter如何调试应用:

void someFunction(double offset) {
  debugger(when: offset > 30.0);
}

在运行应用程序之前,请运行颤振分析来测试代码。该工具(它是darthanalysis工具的包装)将分析代码并帮助查找可能的错误。如果使用IntelliJ的Flutter插件,它将自动启用。

Dart Observatory

Dart解析器大量使用代码中的类型注释来帮助跟踪问题。我们鼓励在任何地方使用它们(避免使用var、无类型参数、无类型列表文本等),因为这是跟踪问题的最快方法。

使用Dart Observatory(或其他Dart调试器,如IntelliJ IDE中的那些)时,可以使用调试器()语句插入编程断点。要使用此函数,必须添加import“dart:developer”;转到相关文档的顶部。
调试器()语句采用可选的when参数,只有当特定条件为真时,才能指定该参数中断

import 'package:flutter/material.dart';

void main() {
  runApp(
    new MaterialApp(
      home: new AppHome(),
    ),
  );
}

Dart print()函数将输出到系统控制台,可以使用flutter日志来查看它(基本上是一个包装器adb-logcat)。
如果一次输出太多,Android有时会丢弃一些日志行。为了避免这种情况,可以在Flutter的基础库中使用debugPrint()。这是一个包打印,它将输出限制在一个级别,以避免被Android内核丢弃。

I/flutter ( 6559): └MaterialApp(state: _MaterialAppState(1009803148))
I/flutter ( 6559):  └ScrollConfiguration()
I/flutter ( 6559):   └AnimatedTheme(duration: 200ms; state: _AnimatedThemeState(543295893; ticker inactive; 

Flutter框架中的许多类都有toString实现。根据惯例,这些输出通常包括对象的runtimeType单行输出,通常是表单中的ClassName(有关此实例的更多信息…)。树中使用的一些类还具有toStringDeep,它返回整个子树的多行描述。一些包含toString详细信息的类将实现一个toStringShort,它只返回对象类型或其他非常简短(一个或两个单词)的描述。

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的“调试”模式,有时也称为“检查”模式。如果使用颤振运行程序。在这种模式下,Dart断言语句被启用,Flutter框架使用它来执行许多运行时检查,以验证是否违反了一些不可变规则。
当不可变规则被违反时,它会向控制台报告一些上下文信息,以帮助跟踪问题的根本原因。

family: "monospace"; size: 48.0; weight: 900; decoration: double Color(0xffffff00) TextDecoration.underline)
I/flutter ( 6559):          └MediaQuery(MediaQueryData(size: Size(411.4, 683.4), devicePixelRatio: 2.625, textScaleFactor: 1.0, padding: EdgeInsets(0.0, 24.0, 0.0, 0.0)))

要关闭调试模式并使用释放模式,请使用flutterrun--release运行应用程序。这也会关闭Observatory调试器。中间模式可以关闭除Observatory之外的所有调试辅助工具。它被称为“概要模式”,可以使用--profile而不是--release。
调试应用程序层
Flutter框架的每一层都提供将其当前状态或事件转储到控制台的功能(使用debugPrint)。
控件层
要转储Widgets库的状态,请调用debugDumpApp()。只要应用程序至少构建了一次(即,在调用build()之后的任何时间),就可以在应用程序不处于构建阶段(即,不在build(方法中调用)的任何时间调用此方法(在调用runApp()之后)。

I/flutter :  │ creator: [root]
I/flutter :  │ offset: Offset(0.0, 0.0)
I/flutter :  │ transform:
I/flutter :  │   [0] 3.5,0.0,0.0,0.0
I/flutter :  │   [1] 0.0,3.5,0.0,0.0
I/flutter :  │   [2] 0.0,0.0,1.0,0.0
I/flutter :  │   [3] 0.0,0.0,0.0,1.0

这是一个“扁平”的树,显示了通过各种构建函数投影的所有小部件(如果在小部件树的根中调用了StringDeepwidget,这就是得到的树)。将看到许多小部件没有出现在应用程序源代码中,因为它们是由框架小部件的build()函数插入的。例如,InkFeature是Material小部件的一个实现细节。

I/flutter : ▄▄▄▄▄▄▄▄ Frame 12         30s 437.086ms ▄▄▄▄▄▄▄▄
I/flutter : Debug print: Am I performing this work more than once per frame?
I/flutter : Debug print: Am I performing this work more than once per frame?
I/flutter : ????????????????????????????????????????????????????

因为当按钮从按下变为释放时调用debugDumpApp(),所以FlatButton对象同时调用setState(),因此它将自己标记为脏。这就是为什么如果查看转储,就会发现特定对象被标记为“脏”。还可以查看哪些手势收听者已注册;在这种情况下,将列出一个GestureDetector,并侦听“轻敲”手势(“轻敲”由TapGesture检测器的toStringShort函数输出)
如果编写自己的小部件,则可以通过重写debugFillProperties()来添加信息。将DiagnosticsProperty对象作为方法参数并调用父方法。toString方法使用此函数来填充小部件描述信息。

I/flutter : SemanticsNode(0; Rect.fromLTRB(0.0, 0.0, 411.4, 683.4))
I/flutter :  ├SemanticsNode(1; Rect.fromLTRB(0.0, 0.0, 411.4, 683.4))
I/flutter :  │ └SemanticsNode(2; Rect.fromLTRB(0.0, 0.0, 411.4, 683.4); canBeTapped)
I/flutter :  └SemanticsNode(3; Rect.fromLTRB(0.0, 0.0, 411.4, 683.4))
I/flutter :    └SemanticsNode(4; Rect.fromLTRB(0.0, 0.0, 82.0, 36.0); canBeTapped; "Dump App")

如果试图调试布局问题,Widgets层树可能不够详细。在这种情况下,可以通过调用debugDumpRenderTree()来转储渲染树。就像debugDumpApp()一样,除了在布局或绘图阶段,可以随时调用此函数。一般来说,从帧回调或事件处理程序调用它是最好的解决方案。
要调用debugDumpRenderTree(),需要添加import包:flatter/rendering。部分';到源文件。

$ flutter run --trace-startup --profile

要收集有关Flutter应用程序启动所需时间的详细信息,可以在运行Flutter运行时使用跟踪启动和配置文件选项。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Flutter(三)——一篇文章掌握Dart语言的用法(三)
Flutter(三)——一篇文章掌握Dart语言的用法(三)
82 0
Flutter(三)——一篇文章掌握Dart语言的用法(一)
Flutter(三)——一篇文章掌握Dart语言的用法(一)
102 0
Flutter(三)——一篇文章掌握Dart语言的用法(二)
Flutter(三)——一篇文章掌握Dart语言的用法(二)
88 0
[Flutter]足够入门的Dart语言系列之面向对象:类之间的6大关系
无论是面向对象编程,还是面向过程、函数式编程,代码与代码之间的组织关系都是最重要的。通过代码的编写、代码间的相互调用、不同代码的合理使用、集合不同的数据和方法,才能...
62 0
[Flutter]足够入门的Dart语言系列之面向对象:类成员的可见性、常量和工厂构造函数详解
类和成员的可见性,这在基于库或包的开发中非常重要,Dart中提供了工厂构造函数,可以方便的实现单例、缓存实例对象、返回子类等,以及常量构造函数的使用......
47 0
[Flutter]足够入门的Dart语言系列之面向对象:类的定义详解、成员和实例使用
类表示的是分类,一类问题或事物,它是对具体或现实世界的抽象。比如动物类、犬科动物类、猫科动物类、房子类、数学类,类是具体事物的描述,它不是指具体的某个动物、某栋房子、某个数学题,而是对它们的概括...
57 0
[Flutter]足够入门的Dart语言系列之函数:匿名函数、作用域闭包、类型别名和内联函数类型
函数在Dart中是对象,因此,可以将函数作为参数传递给另一个函数、作为一个'值'赋值给一个变量。下面主要介绍匿名函数、内联函数类型的使用,以及了解下作用域和闭包...
122 0
[Flutter]足够入门的Dart语言系列之函数:函数定义、调用、5种参数类型和main函数
函数(Function)也被称为方法(Method)。其最直观的理解就是数据中的函数,比如y=f(x),在编程中,f对输入x进行处理,返回结果y,就是一个函数......
130 0
[Flutter]足够入门的Dart语言系列之常见运算符或操作符
Dart中的运算符提供对数据操作和处理的能力,其中的算术运算符、逻辑运算符非常符合现实中的使用情况,其他不同的运算符则有着自己的操作逻辑...
85 0
[Flutter]足够入门的Dart语言系列之流程控制语句:中断和异常(continue/break、try...catch)
循环的执行是通过循环条件来控制的,但是,有时我们想要通过额外的条件判断,来决定是否中断执行,或者中断本次循环而继续执行下次及之后的循环;此外,我们需要对于异常情况的处理...
79 0
+关注
文章
问答
文章排行榜
最热
最新
相关电子书
更多
Flutter企业级应用开发实战手册
立即下载
Flutter技术解析与实战
立即下载
Flutter in action
立即下载


http://www.vxiaotou.com