Flutter 构建模式
目前,Flutter 一共提供了三种运行模式,别离是 Debug、Release 和 Profile 模式。其中,Debug 模式次要用在软件编写过程中,Release 模式次要用于利用公布过程中,而 Profile 模式则次要用于利用性能剖析时,每个模式都有本人非凡的应用场景。上面简介介绍下这几种模式:
Debug 模式
Debug 模式又名调试模式,Debug 模式能够同时在物理设施、仿真器或者模拟器上运行利用。默认状况下,应用 flutter run 命令运行应用程序时就是应用的 Debug 模式。在 Debug 模式下,所有的断言、服务扩大是开启的,并且在模式对疾速开发和运行周期进行了编译优化,当应用调试工具进行代码调试时能够间接连贯到利用的过程里。
Release 模式
Release 模式又名公布模式,此模式只能在物理设施上运行,不能在模拟器上运行。应用 flutter run –release 命令运行应用程序时就是应用的 Release 模式。在 Release 模式下,断点、调试信息和服务扩大是不可用的,并且 Release 模式针对疾速启动、疾速执行和安装包大小进行了优化。
Profile 模式
Profile 模式只能在物理设施上运行,不能在模拟器上运行。此模式次要用于利用性能剖析,一些利用调试能力是被保留的,目标是剖析利用存在的性能问题。Profile 模式和 Release 模式大体雷同,不同点体现在,Profile 模式的某些服务扩大是启用的,某些过程调试伎俩也是开启的。
调试模式
在 Debug 模式下,app 能够被装置在物理设施、仿真器或者模拟器上进行调试。在 Debug 模式下,能够进行如下操作:
- 断点 是开启的。
- 服务扩大是开启的。
- 针对疾速开发和运行周期进行了编译优化(但不是针对执行速度、二进制文件大小或者部署)。
- 调试开启,相似 开发者工具 等调试工具能够连贯到过程里。
如果是在 Web 平台下的调试模式,能够进行如下操作:
- 本次构建 没有 最小化资源并且整个构建 没有 优化性能。
- 为了简化调试,这个 Web 利用应用了 dartdevc 编译器。
默认状况下,运行 flutter run
会应用 Debug 模式,同时 IDE 也反对这些模式。例如,Android Studio 提供了 Run > Debug… 菜单选项,而且在我的项目面板中还有一个三角形的绿色运行按钮图标。
Release 模式
当你想要最大的优化以及最小的占用空间时,就应用 Release 模式来部署 app。release 模式是不反对模拟器或者仿真器的,应用 Release 模式意味着。
- 断点是不可用的。
- 调试信息是不可见的。
- 调试是禁用的。
- 编译针对疾速启动、疾速执行和小的 package 的大小进行了优化。
- 服务扩大是禁用的。
对于 Web 开发来说,应用 Release 模式意味着。
- 这次构建资源曾经被压缩,并且性能得以优化。
- 这个 Web 利用通过 dart2js 编译器构建,以确保更优良的性能。
Profile 模式
在 Profile 模式下,一些调试能力是被保留的,足够剖析你的 app 性能。Profile 模式在仿真器和模拟器上是不可用的,因为他们的行为不能代表实在的性能。和 release 相比,profile 模式有以下不同:
- 一些服务扩大是启用的。例如,反对 performance overlay。
- Tracing 是启用的,一些调试工具,比方 开发者工具 能够连贯到过程里。
在 Web 平台应用 Profile 模式意味着:
- 资源文件没有被压缩,然而整体性能曾经优化。
- 这个 Web 利用通过 dart2js 编译器构建。
调试工具
在 Flutter 利用开发中,有很多工具能够帮忙调试 Flutter 应用程序,常见的如下所示。
- 开发者工具,是一套运行在浏览器的性能及剖析工具。
- Android Studio/IntelliJ 和 VS Code(借助 Flutter 和 Dart 插件)反对内置的源代码调试器,能够设置断点,单步调试,查看数值。
- Flutter inspector,是开发者工具提供的 widget 查看器,也可间接在 Android Studio 和 IntelliJ 中应用(借助 Flutter 插件)。查看器能够可视化展示 widget 树,查看单个 widget 及其属性值,开启性能图层,等等。
开发者工具
要调试及剖析利用,开发者工具可能是你的首选。开发者工具运行在浏览器,反对以下个性:
- 源代码调试器
- Widget 查看器,展现可视化的 widget 树;“widget select”模式,在利用中抉择一个 widget,会在 widget 树间接定位到它的地位。
- 内存剖析
- 工夫线视图,反对跟踪,导入及导出跟踪信息
- 日志视图
如果你在 Debug 模式 或 Profile 模式 运行,那么能够在浏览器关上开发者工具连贯到你的利用。开发者工具不能用在 Release 模式 编译的利用,因为调试和剖析信息都被删除了。如果你要用开发者工具剖析利用,需确保应用 Profile 模式运行利用。
断点调试
和其余语言一样,Flutter 的断点调试反对在 IDE 或编辑器(比方 Android Studio/IntelliJ 和 VS Code)、或者通过编码两种形式。
其中,开发者工具调试器如下图所示。
如果须要,在源代码中设置断点,而后点击工具栏中的【Debug】按钮,或抉择【Run】>【Debug】即可开启调试性能。
开启调试后,能够在控制台看到如下一些信息。
- 底部的 Debugger 窗口会显示出堆栈和变量信息。
- 底部的 Console 窗口会显示具体的日志输入。
- 调试基于默认的启动配置,如果须要自定义,点击抉择指标下拉按钮,抉择 Edit configuration 进行配置。
在进行断点调试时,应用得最多的就是单步调试,三个单步调试按钮在暂停后会变为可用状态。
- 应用 Step in 来进入被调用的办法,在遇到办法内的第一行可执行代码时完结。
- 应用 Step over 间接执行某个办法调用而不进入外部;该按钮在以后办法内按行执行。
- 应用 Step out 来跳出以后办法,这种形式会间接执行完所有以后办法内的语句。
除此之外,咱们还能够应用代码的形式进行断点调试,咱们能够在源代码中应用 debugger()函数来开启断点,当代码运行到此处时就会刮起,如下所示。
import 'dart:developer';
void someFunction(double offset) {debugger(when: offset > 30.0);
// ...
}
Dart 分析器
如果你应用的是 Android Studio 或者 VSCode,那么工具会自带的 Dart 分析器默认会查看代码,并发现可能的谬误。如果你应用命令行,则能够应用 flutter analyze
命令来查看代码。Dart 分析器十分依赖你在代码中增加的类型注解,以帮忙跟踪问题。
另外,咱们能够应用 flutter analyze --flutter-repo
命令将剖析后果打印到管制台上,每次运行这个命名之前,请先运行flutter update-packages
降级最新的包,这样就能够获取最新的依赖包。如果你不这样做,你可能会从 dart:ui 失去一些谬误音讯,比方偏移量等。因为执行flutter analysis
命令时并不会被动去拉取依赖。
对于一次性的 Dart 剖析,间接应用 flutter analyze --flutter-repo
即可,对于间断剖析,则能够应用 flutter analyze --flutter-repo --watch
命令。如果你想晓得多少个成员变量失落了 dartdocs,能够增加一个 dartdocs 参数。
Flutter inspector 工具
Flutter inspector 是剖析 Flutter 组件状态树的利器,Flutter 应用小部件来管制页面组件到布局的精准管制,Flutter inspector 能够帮忙咱们进行如下一些剖析。
- 进行布局剖析,了解布局档次
- 诊断布局问题
在调试模式下,咱们点击 Android Studio 左边 Flutter inspector 按钮即可开启 Flutter inspector 剖析,Flutter inspector 提供了如下的可视化调试工具。
- Select widget mode:启用此按钮后,抉择组件树的代码会主动跳转到对应的源代码外面。
- Refresh tree:从新加载最新的组件信息。
- Slow Animations:加快动画速度,以便进行视觉上的查验。
- Debug Paint:边框、方向的可视化。
- Paint Baselines:每个渲染框在它的每个文本基线上画一条线。
- Repaint Rainbow:查看重绘的重大水平,重大的会被爆红。
除了下面的性能外,咱们还能够点击【Open DevTools】关上 Flutter 的调试页面,能够借助它进行很多性能剖析,前面会具体介绍。
测量利用启动工夫
要收集无关 Flutter 应用程序启动所需工夫的详细信息,能够在运行 flutter run 命令时应用 trace-startup 和 profile 选项,如下所示。
flutter run --trace-startup --profile
跟踪输入被保留到 Flutter 工程目录在 build 目录下,一个名为 start_up_info.json 的 JSON 文件中,输入列出了从应用程序启动到这些跟踪事件(以微秒捕捉)所用的工夫,如下所示。
{
"engineEnterTimestampMicros": 2346054348633,
"timeToFrameworkInitMicros": 812748,
"timeToFirstFrameRasterizedMicros": 1573154,
"timeToFirstFrameMicros": 1221472,
"timeAfterFrameworkInitMicros": 408724
}
对应的具体含意如下:
- 进入 Flutter 引擎时
- 展现利用第一帧时
- 初始化 Flutter 框架时
- 实现 Flutter 框架初始化时
应用 Android Studio 进行调试
Flutter 官网举荐应用 Android Studio 或 VSCode 进行利用开发,和其余语言的调试一样,Dart 代码的调试流程也差不多。如果还没有 Flutter 我的项目,能够新建一个示例我的项目。通过单击首先,点击调试图标(Debug-run icon)同时关上调试面板并在控制台中运行利用,首次运行利用是最慢的,利用启动后,界面应该是上面这样的。
而后,咱们在在 counter++ 这一行上增加断点。在利用里,点击 + 按钮(FloatingActionButton,或者简称 FAB)来减少数字,利用会暂停。
你能够 step in/out/over Dart 语句、热重载和复原执行利用、以及像应用其余调试器一样来应用 Dart 调试器。
Flutter inspector
Flutter inspector 是一个用来可视化以及查看 Flutter widget 树的工具,提供如下性能:
- 理解现有布局
- 诊断布局问题
能够应用 Android Studio 窗口右侧的垂直按钮来关上 Flutter inspector,如下图所示。
Flutter outline
Flutter Outline 是一个可视的显示页面构建办法的性能,留神在构建办法上可能与 widget 树不同,能够应用 Android Studio 窗口右侧的垂直按钮切换 outline 的显示。Tip
: 咱们能够装置一个 Presentation Assistant 插件来辅助咱们进行开发,Presentation Assistant 提供了很多的快捷性能。例如,当焦点在编辑面板中时,输出 command-Shift-A(Mac)或者 shift-control-A(Windows 和 Linux),该插件会同时显示「查找」面板并显示在所有三个平台上执行此操作的提醒。
而后在输入框中输出 attach 关键字,显示如下图。
应用 Android Gradle 调试
为了调试原生代码,你须要一个蕴含 Android 原生代码的利用。在本节中,你将学会如何连贯两个调试器到你的利用:
1)Dart 调试器。
2)Android Gradle 调试器。
创立一个根本的 Flutter 利用,而后替换 lib/main.dart 的代码为以下示例代码。
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
void main() {runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'URL Launcher',
theme: ThemeData(primarySwatch: Colors.blue,),
home: MyHomePage(title: 'URL Launcher'),
);
}
}
class MyHomePage extends StatefulWidget {MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Future<void> _launched;
Future<void> _launchInBrowser(String url) async {if (await canLaunch(url)) {await launch(url, forceSafariVC: false, forceWebView: false);
} else {throw 'Could not launch $url';}
}
Future<void> _launchInWebViewOrVC(String url) async {if (await canLaunch(url)) {await launch(url, forceSafariVC: true, forceWebView: true);
} else {throw 'Could not launch $url';}
}
Widget _launchStatus(BuildContext context, AsyncSnapshot<void> snapshot) {if (snapshot.hasError) {return Text('Error: ${snapshot.error}');
} else {return Text('');
}
}
@override
Widget build(BuildContext context) {
String toLaunch = 'https://flutter.dev';
return Scaffold(
appBar: AppBar(title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(padding: EdgeInsets.all(16.0),
child: Text(toLaunch),
),
RaisedButton(onPressed: () => setState(() {_launched = _launchInBrowser(toLaunch);
}),
child: Text('Launch in browser'),
),
Padding(padding: EdgeInsets.all(16.0)),
RaisedButton(onPressed: () => setState(() {_launched = _launchInWebViewOrVC(toLaunch);
}),
child: Text('Launch in app'),
),
Padding(padding: EdgeInsets.all(16.0)),
FutureBuilder<void>(future: _launched, builder: _launchStatus),
],
),
),
);
}
}
而后,增加 url_launcher 依赖到 pubspec 文件,并执行 flutter pub get 命令拉取依赖包。
name: flutter_app
description: A new Flutter application.
version: 1.0.0+1
dependencies:
flutter:
sdk: flutter
url_launcher: ^3.0.3
cupertino_icons: ^0.1.2
dev_dependencies:
flutter_test:
sdk: flutter
点击调试按钮(Debug-run icon)来同时关上调试面板并启动利用,如下图所示。
点击【Attach debugger to Android process】按钮,从过程对话框中,你应该能够看到每一个设施的入口。抉择 show all processes 来显示每个设施可用的过程。
在调试面板中,你当初应该能够看到一个 Android Debugger 标签页,而后顺次抉择【app_name】>【android】>【app】>【src】>【main】>【java】>【io.flutter plugins】在我的项目面板,而后双击 GeneratedProjectRegistrant 在编辑面板中关上 Java 代码,此时 Dart 和原生调试器都在与同一个过程交互。