2020-9-9 seo達(dá)人
Flutter 構(gòu)建模式
目前,F(xiàn)lutter一共提供了三種運(yùn)行模式,分別是Debug、Release和Profile模式。其中,Debug模式主要用在軟件編寫(xiě)過(guò)程中,Release模式主要用于應(yīng)用發(fā)布過(guò)程中,而Profile模式則主要用于應(yīng)用性能分析時(shí),每個(gè)模式都有自己特殊的使用場(chǎng)景。下面簡(jiǎn)介介紹下這幾種模式:
Debug模式
Debug模式又名調(diào)試模式,Debug模式可以同時(shí)在物理設(shè)備、仿真器或者模擬器上運(yùn)行應(yīng)用。默認(rèn)情況下,使用flutter run命令運(yùn)行應(yīng)用程序時(shí)就是使用的Debug模式。在Debug模式下,所有的斷言、服務(wù)擴(kuò)展是開(kāi)啟的,并且在模式對(duì)快速開(kāi)發(fā)和運(yùn)行周期進(jìn)行了編譯優(yōu)化,當(dāng)使用調(diào)試工具進(jìn)行代碼調(diào)試時(shí)可以直接連接到應(yīng)用的進(jìn)程里。
Release模式
Release模式又名發(fā)布模式,此模式只能在物理設(shè)備上運(yùn)行,不能在模擬器上運(yùn)行。使用flutter run --release命令運(yùn)行應(yīng)用程序時(shí)就是使用的Release模式。在Release模式下,斷點(diǎn)、調(diào)試信息和服務(wù)擴(kuò)展是不可用的,并且Release模式針對(duì)快速啟動(dòng)、快速執(zhí)行和安裝包大小進(jìn)行了優(yōu)化。
Profile模式
Profile模式只能在物理設(shè)備上運(yùn)行,不能在模擬器上運(yùn)行。此模式主要用于應(yīng)用性能分析,一些應(yīng)用調(diào)試能力是被保留的,目的是分析應(yīng)用存在的性能問(wèn)題。Profile模式和Release模式大體相同,不同點(diǎn)體現(xiàn)在,Profile模式的某些服務(wù)擴(kuò)展是啟用的,某些進(jìn)程調(diào)試手段也是開(kāi)啟的。
調(diào)試模式
在 Debug 模式下,app 可以被安裝在物理設(shè)備、仿真器或者模擬器上進(jìn)行調(diào)試。在Debug模式下,可以進(jìn)行如下操作:
斷點(diǎn) 是開(kāi)啟的。
服務(wù)擴(kuò)展是開(kāi)啟的。
針對(duì)快速開(kāi)發(fā)和運(yùn)行周期進(jìn)行了編譯優(yōu)化(但不是針對(duì)執(zhí)行速度、二進(jìn)制文件大小或者部署)。
調(diào)試開(kāi)啟,類似 開(kāi)發(fā)者工具 等調(diào)試工具可以連接到進(jìn)程里。
如果是在 Web 平臺(tái)下的調(diào)試模式,可以進(jìn)行如下操作:
本次構(gòu)建 沒(méi)有 最小化資源并且整個(gè)構(gòu)建 沒(méi)有 優(yōu)化性能。
為了簡(jiǎn)化調(diào)試,這個(gè) Web 應(yīng)用使用了 dartdevc 編譯器。
默認(rèn)情況下,運(yùn)行 flutter run 會(huì)使用 Debug 模式,同時(shí) IDE 也支持這些模式。例如,Android Studio 提供了 Run > Debug… 菜單選項(xiàng),而且在項(xiàng)目面板中還有一個(gè)三角形的綠色運(yùn)行按鈕圖標(biāo) 。
Release 模式
當(dāng)你想要最大的優(yōu)化以及最小的占用空間時(shí),就使用 Release 模式來(lái)部署 app。 release 模式是不支持模擬器或者仿真器的,使用 Release 模式意味著。
斷點(diǎn)是不可用的。
調(diào)試信息是不可見(jiàn)的。
調(diào)試是禁用的。
編譯針對(duì)快速啟動(dòng)、快速執(zhí)行和小的 package 的大小進(jìn)行了優(yōu)化。
服務(wù)擴(kuò)展是禁用的。
對(duì)于Web開(kāi)發(fā)來(lái)說(shuō),使用 Release 模式意味著。
這次構(gòu)建資源已經(jīng)被壓縮,并且性能得以優(yōu)化。
這個(gè) Web 應(yīng)用通過(guò) dart2js 編譯器構(gòu)建,以確保更優(yōu)秀的性能。
Profile 模式
在 Profile 模式下,一些調(diào)試能力是被保留的,足夠分析你的 app 性能。Profile 模式在仿真器和模擬器上是不可用的,因?yàn)樗麄兊男袨椴荒艽碚鎸?shí)的性能。和 release 相比, profile 模式有以下不同:
一些服務(wù)擴(kuò)展是啟用的。例如,支持 performance overlay。
Tracing 是啟用的,一些調(diào)試工具,比如 開(kāi)發(fā)者工具 可以連接到進(jìn)程里。
在 Web 平臺(tái)使用Profile 模式意味著:
資源文件沒(méi)有被壓縮,但是整體性能已經(jīng)優(yōu)化。
這個(gè) Web 應(yīng)用通過(guò) dart2js 編譯器構(gòu)建。
調(diào)試工具
在Flutter應(yīng)用開(kāi)發(fā)中,有很多工具可以幫助調(diào)試 Flutter 應(yīng)用程序,常見(jiàn)的如下所示。
開(kāi)發(fā)者工具,是一套運(yùn)行在瀏覽器的性能及分析工具。
Android Studio/IntelliJ 和 VS Code(借助 Flutter 和 Dart 插件)支持內(nèi)置的源代碼調(diào)試器,可以設(shè)置斷點(diǎn),單步調(diào)試,檢查數(shù)值。
Flutter inspector,是開(kāi)發(fā)者工具提供的 widget 檢查器,也可直接在 Android Studio 和 IntelliJ 中使用(借助 Flutter 插件)。檢查器可以可視化展現(xiàn) widget 樹(shù),查看單個(gè) widget 及其屬性值,開(kāi)啟性能圖層,等等。
開(kāi)發(fā)者工具
要調(diào)試及分析應(yīng)用,開(kāi)發(fā)者工具可能是你的首選。開(kāi)發(fā)者工具運(yùn)行在瀏覽器,支持以下特性:
源代碼調(diào)試器
Widget 檢查器,展示可視化的 widget 樹(shù); “widget select” 模式,在應(yīng)用中選擇一個(gè) widget,會(huì)在 widget 樹(shù)直接定位到它的位置。
內(nèi)存分析
時(shí)間線視圖,支持跟蹤,導(dǎo)入及導(dǎo)出跟蹤信息
日志視圖
如果你在Debug 模式 或Profile 模式 運(yùn)行,那么可以在瀏覽器打開(kāi)開(kāi)發(fā)者工具連接到你的應(yīng)用。開(kāi)發(fā)者工具不能用在 Release 模式 編譯的應(yīng)用,因?yàn)檎{(diào)試和分析信息都被刪除了。如果你要用開(kāi)發(fā)者工具分析應(yīng)用,需確保使用 Profile 模式運(yùn)行應(yīng)用。
在這里插入圖片描述
斷點(diǎn)調(diào)試
和其他語(yǔ)言一樣,F(xiàn)lutter的斷點(diǎn)調(diào)試支持在 IDE 或編輯器(比如 Android Studio/IntelliJ 和 VS Code)、或者通過(guò)編碼兩種方式。
其中,開(kāi)發(fā)者工具調(diào)試器如下圖所示。
在這里插入圖片描述
如果需要,在源代碼中設(shè)置斷點(diǎn),然后點(diǎn)擊工具欄中的 【Debug】 按鈕,或選擇 【Run】 > 【Debug】即可開(kāi)啟調(diào)試功能。
在這里插入圖片描述
開(kāi)啟調(diào)試后,可以在控制臺(tái)看到如下一些信息。
底部的 Debugger 窗口會(huì)顯示出堆棧和變量信息。
底部的 Console 窗口會(huì)顯示詳細(xì)的日志輸出。
調(diào)試基于默認(rèn)的啟動(dòng)配置,如果需要自定義,點(diǎn)擊選擇目標(biāo)下拉按鈕,選擇 Edit configuration 進(jìn)行配置。
在進(jìn)行斷點(diǎn)調(diào)試時(shí),使用得最多的就是單步調(diào)試,三個(gè)單步調(diào)試按鈕在暫停后會(huì)變?yōu)榭捎脿顟B(tài)。
使用 Step in 來(lái)進(jìn)入被調(diào)用的方法,在遇到方法內(nèi)的第一行可執(zhí)行代碼時(shí)結(jié)束。
使用 Step over 直接執(zhí)行某個(gè)方法調(diào)用而不進(jìn)入內(nèi)部;該按鈕在當(dāng)前方法內(nèi)按行執(zhí)行。
使用 Step out 來(lái)跳出當(dāng)前方法,這種方式會(huì)直接執(zhí)行完所有當(dāng)前方法內(nèi)的語(yǔ)句。
除此之外,我們還可以使用代碼的方式進(jìn)行斷點(diǎn)調(diào)試,我們可以在源代碼中使用 debugger()函數(shù)來(lái)開(kāi)啟斷點(diǎn),當(dāng)代碼運(yùn)行到此處時(shí)就會(huì)刮起,如下所示。
import 'dart:developer';
void someFunction(double offset) {
debugger(when: offset > 30.0);
// ...
}
Dart 分析器
如果你使用的是 Android Studio或者VSCode,那么工具會(huì)自帶的 Dart 分析器默認(rèn)會(huì)檢查代碼,并發(fā)現(xiàn)可能的錯(cuò)誤。如果你使用命令行,則可以使用 flutter analyze命令來(lái)檢查代碼。Dart 分析器非常依賴你在代碼中添加的類型注解,以幫助跟蹤問(wèn)題。
另外,我們可以使用flutter analyze --flutter-repo命令將分析結(jié)果打印到控制臺(tái)上,每次運(yùn)行這個(gè)命名之前,請(qǐng)先運(yùn)行flutter update-packages 升級(jí)的包,這樣就可以獲取的依賴包。如果你不這樣做,你可能會(huì)從dart:ui得到一些錯(cuò)誤消息,比如偏移量等。因?yàn)閳?zhí)行flutter analysis 命令時(shí)并不會(huì)主動(dòng)去拉取依賴。
對(duì)于一次性的Dart分析,直接使用flutter analyze --flutter-repo即可,對(duì)于連續(xù)分析,則可以使用flutter analyze --flutter-repo --watch命令。如果你想知道多少個(gè)成員變量丟失了dartdocs,可以添加一個(gè)dartdocs參數(shù)。
Flutter inspector 工具
Flutter inspector 是分析Flutter組件狀態(tài)樹(shù)的利器,F(xiàn)lutter使用小部件來(lái)控制頁(yè)面組件到布局的精準(zhǔn)控制,F(xiàn)lutter inspector 可以幫助我們進(jìn)行如下一些分析。
進(jìn)行布局分析,理解布局層次
診斷布局問(wèn)題
在這里插入圖片描述
在調(diào)試模式下,我們點(diǎn)擊Android Studio右邊Flutter inspector按鈕即可開(kāi)啟Flutter inspector分析,F(xiàn)lutter inspector提供了如下的可視化調(diào)試工具。
在這里插入圖片描述
Select widget mode:?jiǎn)⒂么税粹o后,選擇組件樹(shù)的代碼會(huì)自動(dòng)跳轉(zhuǎn)到對(duì)應(yīng)的源代碼里面。
Refresh tree : 重新加載的組件信息。
Slow Animations:放慢動(dòng)畫(huà)速度,以便進(jìn)行視覺(jué)上的查驗(yàn)。
Debug Paint: 邊框、方向的可視化。
Paint Baselines: 每個(gè)渲染框在它的每個(gè)文本基線上畫(huà)一條線。
Repaint Rainbow:查看重繪的嚴(yán)重程度,嚴(yán)重的會(huì)被爆紅。
除了上面的功能外,我們還可以點(diǎn)擊【Open DevTools】打開(kāi)Flutter的調(diào)試頁(yè)面,可以借助它進(jìn)行很多性能分析,后面會(huì)具體介紹。
在這里插入圖片描述
測(cè)量應(yīng)用啟動(dòng)時(shí)間
要收集有關(guān) Flutter 應(yīng)用程序啟動(dòng)所需時(shí)間的詳細(xì)信息,可以在運(yùn)行 flutter run 命令時(shí)使用 trace-startup 和 profile 選項(xiàng),如下所示。
flutter run --trace-startup --profile
跟蹤輸出被保存到 Flutter 工程目錄在 build 目錄下,一個(gè)名為 start_up_info.json 的 JSON 文件中,輸出列出了從應(yīng)用程序啟動(dòng)到這些跟蹤事件(以微秒捕獲)所用的時(shí)間,如下所示。
{
"engineEnterTimestampMicros": 2346054348633,
"timeToFrameworkInitMicros": 812748,
"timeToFirstFrameRasterizedMicros": 1573154,
"timeToFirstFrameMicros": 1221472,
"timeAfterFrameworkInitMicros": 408724
}
對(duì)應(yīng)的具體含義如下:
進(jìn)入 Flutter 引擎時(shí)
展示應(yīng)用第一幀時(shí)
初始化Flutter框架時(shí)
完成Flutter框架初始化時(shí)
使用Android Studio進(jìn)行調(diào)試
Flutter官方推薦使用Android Studio或VSCode進(jìn)行應(yīng)用開(kāi)發(fā), 和其他語(yǔ)言的調(diào)試一樣,Dart代碼的調(diào)試流程也差不多。如果還沒(méi)有Flutter項(xiàng)目,可以新建一個(gè)示例項(xiàng)目。通過(guò)單擊首先,點(diǎn)擊調(diào)試圖標(biāo)(Debug-run icon)同時(shí)打開(kāi)調(diào)試面板并在控制臺(tái)中運(yùn)行應(yīng)用,首次運(yùn)行應(yīng)用是最慢的,應(yīng)用啟動(dòng)后,界面應(yīng)該是下面這樣的。
在這里插入圖片描述
然后,我們?cè)谠?counter++ 這一行上添加斷點(diǎn)。在應(yīng)用里,點(diǎn)擊 + 按鈕(FloatingActionButton,或者簡(jiǎn)稱 FAB)來(lái)增加數(shù)字,應(yīng)用會(huì)暫停。
在這里插入圖片描述
你可以 step in/out/over Dart 語(yǔ)句、熱重載和恢復(fù)執(zhí)行應(yīng)用、以及像使用其他調(diào)試器一樣來(lái)使用 Dart 調(diào)試器。
Flutter inspector
Flutter inspector 是一個(gè)用來(lái)可視化以及查看 Flutter widget 樹(shù)的工具,提供如下功能:
了解現(xiàn)有布局
診斷布局問(wèn)題
可以使用 Android Studio 窗口右側(cè)的垂直按鈕來(lái)打開(kāi)Flutter inspector,如下圖所示。
在這里插入圖片描述
Flutter outline
Flutter Outline 是一個(gè)可視的顯示頁(yè)面構(gòu)建方法的功能,注意在構(gòu)建方法上可能與 widget 樹(shù)不同,可以使用 Android Studio 窗口右側(cè)的垂直按鈕切換 outline 的顯示。
在這里插入圖片描述
Tip: 我們可以安裝一個(gè) Presentation Assistant 插件來(lái)輔助我們進(jìn)行開(kāi)發(fā),Presentation Assistant 提供了很多的快捷功能。例如,當(dāng)焦點(diǎn)在編輯面板中時(shí),輸入 command-Shift-A(Mac)或者 shift-control-A(Windows 和 Linux),該插件會(huì)同時(shí)顯示「查找」面板并顯示在所有三個(gè)平臺(tái)上執(zhí)行此操作的提示。
在這里插入圖片描述
然后在輸入框中輸入attach關(guān)鍵字,顯示如下圖。
在這里插入圖片描述
使用 Android Gradle 調(diào)試
為了調(diào)試原生代碼,你需要一個(gè)包含 Android 原生代碼的應(yīng)用。在本節(jié)中,你將學(xué)會(huì)如何連接兩個(gè)調(diào)試器到你的應(yīng)用:
1)Dart 調(diào)試器。
2)Android Gradle 調(diào)試器。
創(chuàng)建一個(gè)基本的 Flutter 應(yīng)用,然后替換 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 文件,并執(zhí)行 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
點(diǎn)擊調(diào)試按鈕(Debug-run icon)來(lái)同時(shí)打開(kāi)調(diào)試面板并啟動(dòng)應(yīng)用,如下圖所示。
在這里插入圖片描述
點(diǎn)擊 【Attach debugger to Android process】 按鈕,從進(jìn)程對(duì)話框中,你應(yīng)該可以看到每一個(gè)設(shè)備的入口。選擇 show all processes 來(lái)顯示每個(gè)設(shè)備可用的進(jìn)程。
在這里插入圖片描述
在調(diào)試面板中,你現(xiàn)在應(yīng)該可以看到一個(gè) Android Debugger 標(biāo)簽頁(yè),然后依次選擇【app_name】 > 【android】 > 【app】 > 【src】 >【 main】 > 【java】 > 【io.flutter plugins】在項(xiàng)目面板,然后雙擊 GeneratedProjectRegistrant 在編輯面板中打開(kāi) Java 代碼,此時(shí)Dart 和原生調(diào)試器都在與同一個(gè)進(jìn)程交互。
藍(lán)藍(lán)設(shè)計(jì)( www.teruid.com )是一家專注而深入的界面設(shè)計(jì)公司,為期望卓越的國(guó)內(nèi)外企業(yè)提供卓越的UI界面設(shè)計(jì)、BS界面設(shè)計(jì) 、 cs界面設(shè)計(jì) 、 ipad界面設(shè)計(jì) 、 包裝設(shè)計(jì) 、 圖標(biāo)定制 、 用戶體驗(yàn) 、交互設(shè)計(jì)、 網(wǎng)站建設(shè) 、平面設(shè)計(jì)服務(wù)
藍(lán)藍(lán)設(shè)計(jì)的小編 http://www.teruid.com