25、Flutter开发:调试、性能分析与应用部署全攻略

Flutter开发:调试、性能分析与应用部署全攻略

1. 调试工具概述

Flutter调试基于Dart Observatory工具,它存在于Dart SDK中,可帮助对Dart应用(如Flutter应用)进行性能分析和调试。当Flutter应用以调试模式启动时,该工具会自动运行,实现对应用的调试和性能分析。使用 flutter run 命令后,在“Hot Reload”消息之后会输出地址和端口,此地址即为Observatory UI地址,可通过多种浏览器访问。不过,部分浏览器在显示Observatory工具时存在限制,相关问题可查看:https://github.com/dart-lang/sdk/issues/34107 。

Observatory工具会打印应用运行的各种信息,如Flutter版本、使用的内存、类层次结构和日志等。在该工具页面,可使用所有调试功能,包括:
- 添加和移除断点
- 逐行运行
- 切换和管理隔离区

更多Observatory UI功能和完整使用教程可查看:https://dart-lang.github.io/observatory/get-started.html 。使用Visual Studio Code或Android Studio/IntelliJ等IDE时,不会直接使用Observatory UI工具,IDE会在底层使用Dart Observatory,并通过IDE界面展示其功能。

2. 额外调试特性

2.1 debugger()语句

也称为编程式断点,可在预期条件为真时添加断点。示例代码如下:

void login(String username, String password) {
  debugger(when: password == null);
  ...
}

在上述示例中,仅当 when 参数中的条件为真(即 password 参数为 null )时才会触发断点。暂停执行有助于查看问题发生的原因并做出相应处理,对追踪意外状态和逻辑错误非常有用。

2.2 debugPrint()和print()

print() 方法用于将信息记录到Flutter日志控制台。使用 flutter run 命令时,其日志输出会重定向到控制台,可查看 print() debugPrint() 调用的输出信息。两者的唯一区别在于, debugPrint() 可避免Android内核丢弃日志(Flutter日志只是adb logcat的包装)。更多关于Flutter日志的信息可查看:https://flutter.dev/docs/testing/debugging#print-and-debugprint-with-flutter-logs 。

2.3 asserts

assert() 用于在条件不满足时中断应用执行,与 debugger() 方法类似,但它会抛出 AssertionError 来中断执行,而不是暂停执行。

3. DevTools工具

Dart DevTools被定义为“一套用于Dart和Flutter的性能工具”,它是Observatory工具的下一代版本,IDE已将其集成到内部。其功能与Observatory类似,可帮助进行Flutter应用的性能分析。

3.1 安装和运行

可在终端运行以下命令启用/安装:

pub global activate devtools

或者

flutter packages pub global activate devtools

安装后,可使用以下命令运行工具:

pub global run devtools

或者

flutter packages pub global run devtools

在浏览器中访问显示的页面,使用时需提供运行应用的端口(即Observatory端口),以便DevTool检查应用的测量数据。不同操作系统和IDE的安装步骤详情可查看:https://flutter.github.io/devtools/ 。需注意,目前DevTools套件仍处于发布预览阶段,后续可能会有变化。

4. Flutter应用性能分析

4.1 性能分析的重要性

Flutter旨在提供高帧率和流畅性的高性能应用。性能分析可帮助开发者找出应用中的瓶颈、防止内存泄漏并提升应用性能,与调试一样重要。

4.2 Observatory性能分析器

Observatory为开发者提供了多个工具,通过展示多个指标来测量应用性能并预防相关问题,可通过监控器获取内存、CPU使用情况等信息,以评估应用的不同方面。

4.3 分析模式

使用 flutter run 命令以默认调试模式执行Flutter应用时,其性能与发布模式不同。调试模式使用JIT Dart编译器在应用运行时进行编译,而发布和分析模式使用AOT Dart编译器对应用代码进行预编译。

为进行性能评估,需确保应用以最大能力运行,因此Flutter提供了调试、分析和发布三种执行模式。分析模式下,应用的编译方式与发布模式非常相似,仅增加了启用性能分析所需的开销(即Observatory可连接到应用进程)。此外,性能分析需要使用物理设备,因为模拟器和仿真器无法反映真实设备的性能,硬件差异会影响应用指标和分析结果。

要以分析模式运行应用,需在运行命令中添加 --profile 标志(仅适用于真实设备):

flutter run --profile

在此模式下,可获取检查应用性能所需的所有信息,还可启用性能叠加层。IDE也通过其特定界面提供分析模式。

4.4 性能叠加层

性能叠加层是应用中显示的可视化反馈,提供多个有用的性能统计信息,特别是渲染时间信息。它会显示代表UI和GPU两个线程渲染帧时间的两个图表,当前帧以垂直绿色条显示,还可查看过去300帧的信息,了解关键渲染阶段。Flutter使用多个线程工作,UI和GPU线程负责框架的显示工作,因此在性能叠加层中显示。UI线程执行Dart代码、构建逻辑和小部件描述、创建供GPU线程使用的图层树,而Skia图形库也在此线程运行。此外,Flutter还有运行插件代码的平台线程和运行高开销I/O任务的I/O线程,但这两个线程不会显示在性能叠加层中。更多性能叠加层可帮助改进的内容可查看:https://flutter.dev/docs/testing/ui-performance#the-performance-overlay 。

5. 检查Flutter小部件树

通过调试和性能分析,可在应用投入生产前发现并解决许多问题和性能问题,还能在开发过程中逐步测量应用的执行成本。虽然这两种工具可提供指标,帮助仔细检查代码片段,但对于布局的检查,可借助性能叠加层按帧测量小部件树的渲染时间。此外,还需检查小部件树是否占用过多空间(即是否有过多小部件),以及小部件是否在正确的时间和层级创建,这可通过Flutter检查器完成,在DevTools套件中可访问该功能。

5.1 小部件检查器

小部件检查器是一套有助于开发者进行优化任务的工具,可提供小部件树的详细可视化。在支持的IDE中,插件可通过底层的Flutter小部件检查器工具提供访问该功能的方式,在DevTools套件中也可访问。对于Web开发者来说,它类似于Chrome等浏览器的开发者工具中的元素浏览器。详细探索小部件树有助于发现布局问题,否则这些问题很难被发现。在DevTools中,若不启用跟踪小部件创建标志,工具显示的树会比预期更深,会显示应用中定义的小部件之外的中间小部件;启用该标志后,树会更简单,更接近代码中定义的树,便于跟踪问题,同时还能查看小部件属性细节,帮助发现小的布局问题。

以下是一个简单的流程说明:

graph TD;
    A[启动应用] --> B[打开DevTools];
    B --> C[连接到应用端口];
    C --> D[访问小部件检查器];
    D --> E[查看小部件树];
    E --> F{是否启用跟踪小部件创建};
    F -- 是 --> G[查看简化树];
    F -- 否 --> H[查看更深层次树];

6. 应用部署准备

6.1 部署概述

Flutter为开发者提供了多种资源,开发、性能分析和发布等不同构建方式有其合理性。准备应用发布时,Dart JIT提供的即时编译不再适用,而应使用Dart AOT编译器生成更小、优化且高性能的应用。在Google Play Store和App Store发布应用需要有效的发布者账户,需参考两个平台的文档,在创建应用的发布版本后进行发布。Google有一次性25美元的注册费,可在https://play.google.com/apps/publish/signup/ 注册;App Store每年有99美元的会员费,详情和注册可查看:https://developer.apple.com/support/compare-memberships/ 。

6.2 发布模式

发布模式下,应用会去除调试信息,并以性能为导向进行编译。与分析模式一样,发布模式的应用只能在物理设备上运行。要以发布模式编译应用,需在 flutter run 命令中添加 --release 标志,并连接物理设备。不过,通常使用 flutter build 命令添加该标志来生成目标Android/iOS格式的应用文件,以便进行分发。

6.3 Android应用发布

6.3.1 AndroidManifest和build.gradle文件调整

在Android中,应用的元信息分别在 AndroidManifest.xml build.gradle 文件中提供,需要对这两个文件进行审查和调整。同时,要在Firebase控制台正确配置项目,并将 google-services.json 文件添加到项目中。

6.3.2 AndroidManifest权限审查

审查 AndroidManifest.xml 文件中请求的权限是重要步骤,仅请求所需的权限是良好且推荐的做法,因为请求过多权限可能导致应用被分析并撤销发布。例如,Favors应用的清单权限如下:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.handson">
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.READ_CONTACTS" /> 
    <uses-permission android:name="android.permission.WRITE_CONTACTS"/> 
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-feature
        android:name="android.hardware.camera"
        android:required="false" /> 
   ...
</manifest>

除权限外,还需审查 uses-feature 标签,它可限制应用在具有特定功能的设备上安装。 android.permission.INTERNET 权限由Flutter框架与Observatory工具使用,若应用可离线工作,发布构建时可移除该权限(Favors应用使用了Firebase技术,因此不能移除)。

6.3.3 AndroidManifest元标签审查

还需审查为使用AdMob或Google Maps等服务而添加到应用中的元标签。在Favors应用中,仅添加了AdMob密钥,需审查其值,确保服务使用正确的密钥:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.handson">
    ... 
    <application>
        ...        
        <meta-data
            android:name="com.google.android.gms.ads.APPLICATION_ID"
            android:value="ADMOB-KEY"/>
    </application>
</manifest>

开发过程中,AdMob可使用测试密钥,避免测试被视为API滥用。

6.3.4 AndroidManifest应用名称和图标更改

测试时,应用图标通常是Flutter标志,发布时需替换为独特的图标,以便用户在众多应用中识别。图标和名称在清单的应用标签中定义,默认图标指向Flutter默认图标,需进行以下两项更改:
- 将 label 值更改为应用的最终名称,即用户识别应用的名称。
- 更改 icon 值以替换应用图标。在Android中,图标等图像资源位于 android/app/src/main/res/ 目录下,该目录下有多个文件夹,包含针对特定区域、屏幕尺寸、系统版本等的资源变体。Favors应用的图标可使用Android Asset Studio工具生成,该工具可帮助遵循Android指南生成多个图标变体:https://romannurik.github.io/AndroidAssetStudio/index.html 。需替换每个 mipmap-xxxdpi 文件夹中的 ic_launcher.png 文件,以完全替换应用图标。创建应用图标时,可参考Material Design图标指南:https://material.io/design/iconography/ 。

6.3.5 build.gradle应用ID和版本审查

应用ID值使应用在Play Store和Android系统中具有唯一性,建议使用组织域名作为包名,后跟应用名称。例如,Favors应用使用 com.example.handson 作为应用ID,上传应用到商店后该值无法更改,可在 android/app/build.gradle 文件的 defaultConfig 部分找到相关代码:

defaultConfig {
    applicationId "com.example.handson"
    minSdkVersion 16
    targetSdkVersion 28
    multiDexEnabled true
    versionCode flutterVersionCode.toInteger()
    versionName flutterVersionName
    testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

除应用ID外,还可更改更多设置。在Flutter中,SDK版本通常在以下两种情况下更改:
- 框架要求更改时。
- 使用需要更高最低SDK版本的库时。
可根据需要更改这些值,但需遵循框架要求。

6.3.6 build.gradle应用签名

应用签名是发布前的最后且最重要的步骤,即使不打算在Google Play Store发布应用,签名也能确认应用的所有权,例如发布应用更新时需要签名。首先查看 build.gradle 文件的 buildTypes 部分:

buildTypes {
    release {
        signingConfig signingConfigs.debug
    }
}

其中 signingConfig 属性指向默认签名配置,需将其更改为自己的签名配置,具体步骤如下:
1. 生成开发者密钥库文件(可用于多个应用),使用以下命令:

keytool -genkey -v -keystore DESTINATION_FILEPATH -keyalg RSA -keysize 2048 -validity 10000 -alias key

按照提示操作,将在指定路径生成密钥库,例如 <your users dir/my-release-key.keystore> ,之后需在 build.gradle 文件中引用该文件。
2. 创建 android/key.properties 文件,内容如下:

storePassword=<password used for generating key>
keyPassword=<password used for generating key>
keyAlias=key
storeFile=key store file path(i.e. </your users dir/my-release-key.keystore>)
  1. build.gradle 文件中加载新的 key.properties 文件,并为其创建新的 signingConfig 类:
def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
    keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}
android{
  ...
  signingConfigs {
    release {
        keyAlias keystoreProperties['keyAlias']
        keyPassword keystoreProperties['keyPassword']
        storeFile file(keystoreProperties['storeFile'])
        storePassword keystoreProperties['storePassword']
    }
  }
}
  1. 将上述代码片段添加到 android 部分之前,在 signingConfigs 子部分声明签名配置,最后将 buildTypes 部分中发布选项的 signingConfig 属性替换为新的配置:
android {
  ...
  buildTypes {
      release {
          signingConfig signingConfigs.release
      }
  }
}

完成上述操作后,使用 flutter build apk flutter run --release 命令时,应用将使用自己的密钥进行签名。调整完成后,即可构建和分发应用。最后,需检查应用的 versionCode versionName 值,它们会自动从 pubspec.yaml 文件中填充,因此审查该文件也很重要。使用 flutter build apk 命令构建 .apk 文件后,可使用 flutter install 命令将其安装到连接的物理设备上,要发布到Play Store的文件位于 build/app/outputs/apk/app.apk 。此外,还可对代码进行压缩和混淆,以减小应用大小并防止逆向工程:https://github.com/flutter/flutter/wiki/Obfuscating-Dart-Code 。

通过以上步骤,开发者可以全面地对Flutter应用进行调试、性能分析,并完成应用的部署准备工作,确保应用以最佳状态发布到应用商店。

7. 总结与注意事项

7.1 工具使用总结

在Flutter开发过程中,我们使用了多种工具来辅助开发,以下是这些工具的总结表格:
| 工具名称 | 功能描述 | 使用场景 | 操作步骤 |
| — | — | — | — |
| Dart Observatory | 用于Flutter调试和性能分析,提供应用的多种信息,如内存、类层次结构等 | 调试和性能分析阶段 | 以调试模式启动Flutter应用,使用 flutter run 命令获取Observatory UI地址,通过浏览器访问 |
| DevTools | 一套用于Dart和Flutter的性能工具,是Observatory的下一代版本 | 性能分析和优化 | 安装: pub global activate devtools flutter packages pub global activate devtools ;运行: pub global run devtools flutter packages pub global run devtools ,连接应用端口进行分析 |
| 小部件检查器 | 提供小部件树的详细可视化,帮助发现布局问题 | 布局优化阶段 | 打开DevTools,连接应用端口,访问小部件检查器,可选择是否启用跟踪小部件创建查看不同的小部件树 |

7.2 模式总结

Flutter提供了三种执行模式,每种模式有不同的特点和使用场景,具体如下:
| 模式名称 | 编译方式 | 性能特点 | 使用场景 | 命令示例 |
| — | — | — | — | — |
| 调试模式 | JIT Dart编译器在应用运行时编译 | 性能相对较低,便于调试 | 开发和调试阶段 | flutter run |
| 分析模式 | 类似发布模式,使用AOT Dart编译器预编译,增加性能分析开销 | 接近真实性能,可进行性能分析 | 性能评估和优化阶段 | flutter run --profile |
| 发布模式 | AOT Dart编译器预编译,去除调试信息 | 性能最优,用于正式发布 | 应用发布阶段 | flutter build --release |

7.3 注意事项

  • 物理设备的使用 :在性能分析和发布模式下,建议使用物理设备,因为模拟器和仿真器无法准确反映真实设备的性能,可能会影响分析结果。
  • 权限管理 :在Android应用发布时,要仔细审查 AndroidManifest.xml 文件中的权限请求,仅请求必要的权限,避免因权限问题导致应用发布受阻。
  • 应用ID和签名 :应用ID在上传到应用商店后无法更改,要确保其唯一性和准确性;应用签名是确认应用所有权的重要步骤,务必按照正确的步骤进行签名配置。

7.4 整体流程回顾

以下是Flutter应用从开发到发布的整体流程mermaid流程图:

graph LR;
    A[开发阶段] --> B[调试阶段];
    B --> C[性能分析阶段];
    C --> D{是否满足性能要求};
    D -- 是 --> E[发布准备阶段];
    D -- 否 --> C;
    E --> F[应用签名];
    F --> G[构建应用文件];
    G --> H[发布到应用商店];

8. 常见问题及解决方案

8.1 调试工具相关问题

  • 问题描述 :无法访问Observatory UI地址。
    • 可能原因 :应用未以调试模式启动;网络问题;浏览器不支持。
    • 解决方案 :确保以调试模式启动应用,检查网络连接,尝试更换支持的浏览器,可参考https://github.com/dart-lang/sdk/issues/34107 查看浏览器支持情况。
  • 问题描述 :DevTools无法连接到应用端口。
    • 可能原因 :应用未正常运行;端口被占用;DevTools版本不兼容。
    • 解决方案 :检查应用是否正常运行,使用命令查看端口占用情况并释放端口,更新DevTools到最新版本。

8.2 性能分析相关问题

  • 问题描述 :性能分析结果不准确。
    • 可能原因 :使用了模拟器或仿真器;分析模式配置错误。
    • 解决方案 :使用物理设备进行性能分析,确保以正确的分析模式( flutter run --profile )运行应用。
  • 问题描述 :性能叠加层显示异常。
    • 可能原因 :应用代码存在问题;Flutter版本不兼容。
    • 解决方案 :检查应用代码,更新Flutter到最新版本。

8.3 应用部署相关问题

  • 问题描述 :应用签名失败。
    • 可能原因 :密钥库文件路径错误;密码错误;签名配置错误。
    • 解决方案 :检查密钥库文件路径和密码是否正确,按照正确的步骤在 build.gradle 文件中配置签名信息。
  • 问题描述 :应用无法在应用商店发布。
    • 可能原因 :应用ID重复;权限问题;应用信息不完整。
    • 解决方案 :确保应用ID的唯一性,审查 AndroidManifest.xml 文件中的权限请求,完善应用信息。

9. 未来趋势与展望

随着Flutter技术的不断发展,调试、性能分析和应用部署工具也将不断完善。未来可能会出现更智能、更便捷的工具,帮助开发者更高效地进行开发和优化。例如,自动化的性能分析工具可以自动检测应用中的性能瓶颈并提供优化建议;更友好的部署工具可以简化应用发布的流程,减少人工操作。

同时,Flutter在跨平台开发领域的应用将越来越广泛,开发者对工具的需求也会更加多样化。因此,开发者需要不断关注技术的发展趋势,学习和掌握新的工具和技术,以适应不断变化的开发环境。

10. 结论

Flutter开发过程中的调试、性能分析和应用部署是确保应用质量和性能的重要环节。通过合理使用Dart Observatory、DevTools等工具,开发者可以有效地发现和解决应用中的问题,优化应用性能。在应用部署方面,遵循正确的步骤进行应用签名、构建和发布,可以确保应用顺利发布到应用商店。

在开发过程中,要注意物理设备的使用、权限管理、应用ID和签名等问题,避免因这些问题导致开发和发布受阻。同时,要关注技术的发展趋势,不断学习和掌握新的工具和技术,以提高开发效率和应用质量。

希望本文对开发者在Flutter开发过程中的调试、性能分析和应用部署工作有所帮助,让开发者能够更加轻松地开发出高质量的Flutter应用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值