当前位置: 首页 > news >正文

Flutter学习四:Flutter开发基础(六)调试Flutter应用

目录

0 引言

1 调试Flutter应用

1.1 日志与断点

1.1.1 debugger() 声明

1.1.2 print和debugPrint

1.1.3 调试模式、中间模式、发布模式

1.1.4 断点

1.2 调试应用程序层

1.2.1 转储Widgets树

1.2.2  转储渲染树

1.2.3 转储Layer树

1.2.4 转储语义树

1.2.5 调度(打印帧的开始和结束)

1.2.6 可视化调试

1.2.7 调试动画

1.2.8 调试性能问题

1.2.9 统计应用启动时间

1.2.10  跟踪Dart代码性能

1.3 官方可视化调试工具DevTools


0 引言

本文是对第二版序 | 《Flutter实战·第二版》 (flutterchina.club)的学习和总结。

1 调试Flutter应用

1.1 日志与断点

1.1.1 debugger() 声明

当使用Dart Observatory(调试模式时自动启用),可以使用debugger()语句插入编程式断点。

import 'dart:developer';/*debugger()语句采用一个可选的when参数,可以指定该参数仅在特定条件为真时中断
*/
void someFunction(double offset) {debugger(when: offset > 30.0);// ...
}

1.1.2 print和debugPrint

  • Dart  print()功能将输出到系统控制台,可以使用flutter logs来查看它。如果一次输出太多,Android有时会丢弃一些日志行。
  • 推荐使用Flutter的foundation库中的debugPrint(),它封装了 print,将一次输出的内容长度限制在一个级别(内容过多时会分批输出),避免被Android内核丢弃。

1.1.3 调试模式、中间模式、发布模式

  • 在Flutter应用调试过程中,Dart assert语句被启用,当某个规则被违反时,就会在控制台打印错误日志,并带上一些上下文信息来帮助追踪问题的根源。
  • 发布模式会关闭Observatory调试器,使用flutter run --release运行应用程序即可打开发布模式。
  • 中间模式“profile mode”可以关闭除Observatory之外所有的调试辅助工具,使用flutter run --profile运行应用程序即可打开中间模式。

1.1.4 断点

开发过程中,断点是最实用的调试工具之一,以 Android Studio 为例:比如在 93 行打了一个断点,一旦代码执行到这一行就会暂停,这时我们可以看到当前上下文所有变量的值,然后可以选择一步一步的执行代码。

1.2 调试应用程序层

Flutter框架的每一层都提供了将其当前状态或事件转储(dump)到控制台(使用debugPrint)的功能。

1.2.1 转储Widgets树

  • 要转储Widgets树的状态,请调用debugDumpApp()
  • 需要在调用runApp()之后调用
  • 不能在build()方法内调用
  • 不要在布局或绘制阶段调用
  • 从frame 回调或事件处理器中调用是最佳方案
import 'package:flutter/material.dart';void main() {runApp(MaterialApp(home: AppHome(),),);
}class AppHome extends StatelessWidget {@overrideWidget build(BuildContext context) {return Material(child: Center(child: TextButton(onPressed: () {// 当按钮从被按下变为被释放时debugDumpApp()被调用debugDumpApp();},child: Text('Dump App'),),),);}
}

调用后输出这样的内容(精确的细节会根据框架的版本、设备的大小等等而变化): 

I/flutter ( 6559): WidgetsFlutterBinding - CHECKED MODE
I/flutter ( 6559): RenderObjectToWidgetAdapter<RenderBox>([GlobalObjectKey RenderView(497039273)]; renderObject: RenderView)
I/flutter ( 6559): └MaterialApp(state: _MaterialAppState(1009803148))
I/flutter ( 6559):  └ScrollConfiguration()
I/flutter ( 6559):   └AnimatedTheme(duration: 200ms; state: _AnimatedThemeState(543295893; ticker inactive; ThemeDataTween(ThemeData(Brightness.light Color(0xff2196f3) etc...) → null)))
I/flutter ( 6559):    └Theme(ThemeData(Brightness.light Color(0xff2196f3) etc...))
I/flutter ( 6559):     └WidgetsApp([GlobalObjectKey _MaterialAppState(1009803148)]; state: _WidgetsAppState(552902158))
I/flutter ( 6559):      └CheckedModeBanner()
I/flutter ( 6559):       └Banner()
I/flutter ( 6559):        └CustomPaint(renderObject: RenderCustomPaint)
I/flutter ( 6559):         └DefaultTextStyle(inherit: true; color: Color(0xd0ff0000); 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)))
I/flutter ( 6559):           └LocaleQuery(null)
I/flutter ( 6559):            └Title(color: Color(0xff2196f3))
... #省略剩余内容

1.2.2  转储渲染树

  • 调试布局问题时,转储Widget树可能不够详细,需要转储渲染树
  • 要转储渲染树,请调用debugDumpRenderTree()
  • 要调用debugDumpRenderTree(),需要添加import'package:flutter/rendering.dart'

 对于上面的例子,它会输出:

I/flutter ( 6559): RenderView
I/flutter ( 6559):  │ debug mode enabled - android
I/flutter ( 6559):  │ window size: Size(1080.0, 1794.0) (in physical pixels)
I/flutter ( 6559):  │ device pixel ratio: 2.625 (physical pixels per logical pixel)
I/flutter ( 6559):  │ configuration: Size(411.4, 683.4) at 2.625x (in logical pixels)
I/flutter ( 6559):  │
I/flutter ( 6559):  └─child: RenderCustomPaint
I/flutter ( 6559):    │ creator: CustomPaint ← Banner ← CheckedModeBanner ←
I/flutter ( 6559):    │   WidgetsApp-[GlobalObjectKey _MaterialAppState(1009803148)] ←
I/flutter ( 6559):    │   Theme ← AnimatedTheme ← ScrollConfiguration ← MaterialApp ←
I/flutter ( 6559):    │   [root]
I/flutter ( 6559):    │ parentData: <none>
I/flutter ( 6559):    │ constraints: BoxConstraints(w=411.4, h=683.4)
I/flutter ( 6559):    │ size: Size(411.4, 683.4)
... # 省略

1.2.3 转储Layer树

  • 调试合成问题,调用debugDumpLayerTree()
  • 可以理解为渲染树是可以分层的,而最终绘制需要将不同的层合成起来,而Layer则是绘制时需要合成的层

对于上面的例子,它会输出下图内容。这是根LayertoStringDeep输出的。根部的变换是应用设备像素比的变换; 在这种情况下,每个逻辑像素代表3.5个设备像素。

I/flutter : TransformLayer
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
I/flutter :  │
I/flutter :  ├─child 1: OffsetLayer
I/flutter :  │ │ creator: RepaintBoundary ← _FocusScope ← Semantics ← Focus-[GlobalObjectKey MaterialPageRoute(560156430)] ← _ModalScope-[GlobalKey 328026813] ← _OverlayEntry-[GlobalKey 388965355] ← Stack ← Overlay-[GlobalKey 625702218] ← Navigator-[GlobalObjectKey _MaterialAppState(859106034)] ← Title ← ⋯
I/flutter :  │ │ offset: Offset(0.0, 0.0)
I/flutter :  │ │
I/flutter :  │ └─child 1: PictureLayer
I/flutter :  │
I/flutter :  └─child 2: PictureLayer

1.2.4 转储语义树

  • 语义树:呈现给系统可访问性API的树
  • 转储语义树,要调用debugDumpSemanticsTree() 
  •  要调用debugDumpSemanticsTree() ,必须首先启用辅助功能,例如启用系统辅助工具或SemanticsDebugger

对于上面的例子,它会输出:

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")

1.2.5 调度(打印帧的开始和结束)

  • 切换debugPrintBeginFrameBanner和debugPrintEndFrameBanner布尔值可以将帧的开始和结束打印到控制台,找出相对于帧的开始/结束事件发生的位置。
  • debugPrintScheduleFrameStacks可以用来打印导致当前帧被调度的调用堆栈

例如:

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 : ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀

1.2.6 可视化调试

所有这些标志只能在调试模式下工作。

通常,Flutter框架中以“debug...” 开头的任何内容都只能在调试模式下工作。

设置debugPaintSizeEnabledtrue以可视方式调试布局问题:

  • 这是来自rendering库的布尔值。
  • 它可以在任何时候启用,并在为true时影响绘制。
  • 设置它的最简单方法是在void main()的顶部设置。

当它被启用时,所有的盒子都会得到一个明亮的深青色边框:

  • padding(来自widget如Padding)显示为浅蓝色,
  • 子widget周围有一个深蓝色框,
  • 对齐方式(来自widget如Center和Align)显示为黄色箭头,
  • 空白(如没有任何子节点的Container)以灰色显示。

debugPaintBaselinesEnabled做了类似的事情,但对于具有基线的对象,文字基线以绿色显示,表意(ideographic)基线以橙色显示。

debugPaintPointersEnabled标志打开一个特殊模式,任何正在点击的对象都会以深青色突出显示。 这可以帮助我们确定某个对象是否以某种不正确的方式进行hit测试(Flutter检测点击的位置是否有能响应用户操作的widget),例如,如果它实际上超出了其父项的范围,首先不会考虑通过hit测试。

debugPaintLayerBordersEnabled标志调试合成图层,例如以确定是否以及在何处添加RepaintBoundary widget。该标志用橙色或轮廓线标出每个层的边界,或者使用debugRepaintRainbowEnabled标志重绘时,该层会被一组旋转色所覆盖。

1.2.7 调试动画

调试动画最简单的方法是减慢它们的速度:

  • 将timeDilation (opens new window)变量(在scheduler库中)设置为大于1.0的数字,例如50.0。
  • 最好在应用程序启动时只设置一次。
  • 如果在运行中更改它,尤其是在动画运行时将其值改小,则在观察时可能会出现倒退。

1.2.8 调试性能问题

  • 要了解应用程序导致重新布局或重新绘制的原因,分别设置debugPrintMarkNeedsLayoutStacks和 debugPrintMarkNeedsPaintStacks标志。
  •  每当渲染盒被要求重新布局和重新绘制时,这些都会将堆栈跟踪记录到控制台。
  • 可以使用services库中的debugPrintStack()方法按需打印堆栈痕迹。

1.2.9 统计应用启动时间

  • 要收集有关Flutter应用程序启动所需时间的详细信息,
  • 可以在运行flutter run时使用trace-startupprofile选项。
$ flutter run --trace-startup --profile

跟踪输出保存为start_up_info.json,在Flutter工程目录在build目录下。输出列出了从应用程序启动到这些跟踪事件(以微秒捕获)所用的时间:

  • 进入Flutter引擎时.
  • 展示应用第一帧时.
  • 初始化Flutter框架时.
  • 完成Flutter框架初始化时.

例如 :

{"engineEnterTimestampMicros": 96025565262,"timeToFirstFrameMicros": 2171978,"timeToFrameworkInitMicros": 514585,"timeAfterFrameworkInitMicros": 1657393
}

1.2.10  跟踪Dart代码性能

跟踪和测量Dart任意代码段的wall/CPU时间(类似Android上使用systrace):

  • 运行flutter run时带有--profile标志,
  • 使用dart:developer的Timeline工具来包含你想测试的代码块,
  • 打开你应用程序的Observatory timeline页面,在“Recorded Streams”中选择‘Dart’复选框,并执行你想测量的功能。
  • 刷新页面将在Chrome的跟踪工具中显示应用按时间顺序排列的timeline记录。
Timeline.startSync('interesting function');
// iWonderHowLongThisTakes();
Timeline.finishSync();

1.3 官方可视化调试工具DevTools

Flutter DevTools 是一套 Dart 和 Flutter 的性能调试工具。

它将各种调试工具和能力集成在一起,并提供可视化调试界面。

可以用 Flutter DevTools 开发工具来实现的操作:

  • 检查 Flutter 应用程序的 UI 组件布局和状态;

  • 在 Flutter 应用程序中诊断 UI 性能过低的问题;

  • Flutter 和 Dart 应用的 CPU 性能检测;

  • 为 Flutter 应用进行网络性能检测;

  • 为 Flutter 或 Dart 应用进行源码级的调试;

  • 在 Flutter 或 Dart 命令行应用中测试内存问题;

  • 查看有关正在运行的Flutter或Dart命令行应用程序的常规日志和诊断信息。
  • 查看正在运行的 Flutter 或 Dart 的命令行应用程序相关的常规日志和诊断信息。

 在 Android Studio 上安装和运行开发者工具

 在 VS Code 里安装和使用开发者工具

相关文章:

Flutter学习四:Flutter开发基础(六)调试Flutter应用

目录 0 引言 1 调试Flutter应用 1.1 日志与断点 1.1.1 debugger() 声明 1.1.2 print和debugPrint 1.1.3 调试模式、中间模式、发布模式 1.1.4 断点 1.2 调试应用程序层 1.2.1 转储Widgets树 1.2.2 转储渲染树 1.2.3 转储Layer树 1.2.4 转储语义树 1.2.5 调度&…...

新的开始(开始更新笔记)

首先感谢关注我的小伙伴&#xff0c;以后在求职或者选择方向的时候&#xff0c;感觉迷茫的时候&#xff0c;可以加我聊聊。 一路走来&#xff0c;跌跌撞撞&#xff0c;磕磕碰碰&#xff0c;经历了很多&#xff0c;记得上一次的更新笔记还是2021年。 首先说一下我的经历&#…...

爬虫工具-替换js文件ReRes插件/Gores插件

目录 一、ReRes插件二、Gores插件 一、ReRes插件 用途&#xff1a;爬虫逆向过程中一些文件需要替换时 ① 原始网站js文件有无限debugger&#xff0c;复制原始网站js文件&#xff0c;删掉无限debugger相关代码保存为新的js文件&#xff1b;用ReRes插件进行替换② 原始网站js文件…...

多任务学习用于多模态生物数据分析

目前的生物技术可以同时测量来自同一细胞的多种模态数据&#xff08;例如RNA、DNA可及性和蛋白质&#xff09;。这需要结合不同的分析任务&#xff08;如多模态整合和跨模态分析&#xff09;来全面理解这些数据&#xff0c;推断基因调控如何驱动生物多样性。然而&#xff0c;目…...

使用less命令搜索文件中的关键字

目录 介绍常用搜索技巧实例 介绍 less 与 more 类似&#xff0c;less 可以随意浏览文件&#xff0c;支持翻页和搜索&#xff0c;支持向上翻页和向下翻页。 语法 less [参数] 文件 参数说明&#xff1a; -b <缓冲区大小> 设置缓冲区的大小 -e 当文件显示结束后&#xff…...

【kubernetes系列】Kubernetes之Taints和tolerations

概述 节点亲和性是pod的一种属性&#xff08;优先选择或硬性要求&#xff09;&#xff0c;它使 pod 被优先分配到一类特定的节点上。而Taint则相反&#xff0c;它使节点能够排斥一类特定的 pod。 Taints&#xff08;污点&#xff09;与tolerations&#xff08;容忍度&#xf…...

宝剑锋从磨砺出 梅花香自苦寒来(高考志愿篇)

各省高考成绩已出&#xff0c;又到一年高考季。张雪峰提到&#xff1a;“普通家庭不要光谈理想&#xff0c;也要谈落地。”志愿怎样填报、选专业还是选学校、什么专业好就业、高考志愿主要看什么&#xff1f;针对这些疑问&#xff0c;你对正在选志愿的毕业生们有什么建议吗&…...

Jtti:怎样进行sql server2000 日志传送

在 SQL Server 2000 中&#xff0c;日志传送是指将事务日志从一个主服务器传送到一个或多个备份服务器的过程。这个过程确保备份服务器上的数据库保持与主服务器上的数据库同步。 要进行 SQL Server 2000 的日志传送&#xff0c;需要进行以下步骤&#xff1a; 配置主服务器&…...

MyBatis-Plus:条件构造器Wrapper

目录 1.Wrapper概述 1.1.Wrapper的继承关系 1.2.Wapper介绍 1.3.各个构造器使用区别 1.4.构造器常用方法 2.Wrapper常用构造器介绍 2.1.QueryWrapper 2.2.UpdateWrapper 2.3.LambdaQueryWrapper 2.4.AbstractWrapper 3. Lambda条件构造器 3.1.示例 4.鸣谢 MyBati…...

SNMP 计算机网络管理 实验1(二) 练习与使用Wireshark抓取SNMP数据包抓包之 任务三分析并验证TCP三次握手建立连接时三次握手工作过程

⬜⬜⬜ &#x1f430;&#x1f7e7;&#x1f7e8;&#x1f7e9;&#x1f7e6;&#x1f7ea;(*^▽^*)欢迎光临 &#x1f7e7;&#x1f7e8;&#x1f7e9;&#x1f7e6;&#x1f7ea;&#x1f430;⬜⬜⬜ ✏️write in front✏️ &#x1f4dd;个人主页&#xff1a;陈丹宇jmu &am…...

【UE5 Cesium】03-Cesium for Unreal 添加本地数据集

上一篇&#xff1a;【UE5 Cesium】02-Cesium for Unreal 添加在线数据集 步骤 1. 在官网&#xff08;Adding Datasets – Cesium&#xff09;上下载一个示例 下载的是一个名为“Tileset.zip”的压缩文件 解压后文件内容如下 2. 打开虚幻编辑器&#xff0c;点击“Blank 3D Tiles…...

数通王国历险记之地址分析协议(ARP)

系列文章目录 数通王国历险记&#xff08;4&#xff09; 目录 前言 一&#xff0c;什么是地址解析协议&#xff08;ARP&#xff09; 二&#xff0c;封装和解封装 三&#xff0c;为什么需要地址解析协议&#xff08;ARP&#xff09; 四&#xff0c;ARP的验证实验 4.1&#x…...

Mac端显示服务器上show的内容

Mac端显示服务器上show的内容 1. 需求描述 在Mac端&#xff08;终端和PyCharm中&#xff09;编写代码&#xff0c;在服务器端运行程序。需要在Mac端显示服务器端运行的内容&#xff0c;比如&#xff0c;运行的视频等。 2. 常见报错 SSH 运行命令时报错示例。 (cv) czjing…...

【SQL】每类视频近一个月的转发量/率

【问题】 统计在有用户互动的最近一个月&#xff08;按包含当天在内的近30天算&#xff0c;比如10月31日的近30天为10.2~10.31之间的数据&#xff09;中&#xff0c;每类视频的转发量和转发率&#xff08;保留3位小数&#xff09;。 【数据】 用户-视频互动表 tb_user_video…...

chatgpt读论文

在当今的数字化时代&#xff0c;人工智能(AI)正在颠覆我们的生活方式。 OpenAI的GPT系列模型——尤其是最新一代的GPT-4和它的聊天机器人版本ChatGPT——是最近AI进步的显著代表。通过深度学习和海量数据训练&#xff0c;这些模型已经可以生成出色的人类般的文本。它们可以被用…...

关于visual studio 2010 及以上版本 引入boost库的最新解决方法

之前没有怎么用到boost库&#xff0c;出来实习需要去编译一些代码&#xff0c;需要引入boost第三方库&#xff0c;在这过程中&#xff0c;一直出现 LINK : fatal error LNK1104: 无法打开文件“libboost_filesystem-vc100-mt-gd-x3 错误&#xff0c; 但是也确实是跟其他教程学过…...

SpringBoot+ Dubbo + Mybatis + Nacos +Seata整合来实现Dubbo分布式事务

1.简介 “ 本文主要介绍SpringBoot2.1.5 Dubbo 2.7.3 Mybatis 3.4.2 Nacos 1.1.3 Seata 0.8.0整合来实现Dubbo分布式事务管理&#xff0c;使用Nacos 作为 Dubbo和Seata的注册中心和配置中心,使用 MySQL 数据库和 MyBatis来操作数据。 ” 如果你还对SpringBoot、Dubbo、Nacos…...

MongoDB使用

文档连接: link 创建表 不需要创建表的语句&#xff0c;当插入表的第一条语句时&#xff0c;会隐式的创建表。 增 插入一条 db.people.insertOne({ user_id: "bcd001", age: 45, status: "A" } )插入多条 db.collection.insertMany([ <document 1&g…...

C#文件安全管理解析

在实际的项目开发中&#xff0c;我们经常需要使用到文件的I/O操作&#xff0c;主要包含对文件的增改删查等操作&#xff0c;这些基本的操作我们都是很熟悉&#xff0c;但是较少的人去考虑文件的安全和操作的管理等方面&#xff0c;例如文件的访问权限管理&#xff0c;文件数据的…...

基于Dubbo分布式学校信息管理系统设计与实现

一、引言 1.1 课题背景 随着时代的发展与进步,计算机网络也随之日益完善,渐渐覆盖了我们生活的各个方面。在信息化和数字化的时代背景下,使用计算机管理学校信息来提升教育工作的质量和效率,是大势所趋,所以近年来,随着网络技术的不断发展,使用信息管理系统的学校越来…...

oracle面试问题和笔记整理

oracle面试笔记 ORACLE 面试问题-技术篇(2) 如何判断数据库的时区? 解答:SELECT DBTIMEZONE FROM DUAL; 解释GLOBAL_NAMES设为TRUE的用途 解答:GLOBAL_NAMES指明联接数据库的方式。如果这个参数设置为TRUE, 在建立数据库链接时就必须用相同的名字连结远程数据库 23。如何…...

Hadoop_Yarn实践 (三) => (Yarn的基础架构、原理、容量/公平调度器、Tool接口、Yarn常用命令、核心参数)

目录 Hadoop_HDFS、Hadoop_MapReduce、Hadoop_Yarn 实践 (三)一、Hadoop_HDFS二、Hadoop_MapReduce三、Hadoop_Yarn1、Yarn资源调度1.1、基础架构1.2、Yarn的工作调度机制&#xff08;Job提交过程&#xff09;1.3、Yarn 调度器和调度算法1.3.1、先进先出调度器&#xff08;FIFO…...

postgresql 从应用角度看快照snapshot使用,事务隔离控制不再神密

​专栏内容&#xff1a;postgresql内核源码分析 个人主页&#xff1a;我的主页 座右铭&#xff1a;天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物. 快照使用 快照是事务中使用&#xff0c;配合事务的隔离级别&#xff0c;体现出不同的可见性。…...

mysql(mariadb)读写分离部署

目录 一、原理 二、准备环境 三、部署mysql主从复制 1.五台服务器下载mariadb 2.修改master配置文件&#xff0c;重启数据库 3.登录mysql创建replication 4.从服务器登录验证 5.获得master服务器 DB的相关信息 6.备份master原有数据 7.修改slave1、slave2配置 8. 进入…...

ES-工作原理

前言 ​ 搜索引擎是对数据的检索&#xff0c;而数据总体分为两种&#xff1a;结构化数据和非结构化数据。而对于结构化数据&#xff0c;因为他们具有特定的结构&#xff0c;所以一般都是可以通过关系型数据库MySQL/oracle的二维表的方式存储和搜索&#xff0c;也可以建立索引。…...

C++小结(4)

C 字符串 C 提供了两种类型的字符串表示形式&#xff1a; C 风格字符串C 引入的 string 类类型 C 风格字符串 C 风格的字符串起源于 C 语言&#xff0c;并在 C 中继续得到支持。字符串实际上是使用 null 字符 \0 终止的一维字符数组。因此&#xff0c;一个以 null 结尾的字…...

Java框架之spring 的 messaging

写在前面 本文看下spring message相关的内容。 1&#xff1a;Message&#xff1f;Messaging&#xff1f; Message是消息的意思&#xff0c;是一个名词。而Messaging是一个动名词&#xff0c;是将消息发送出去的意思&#xff0c;因此&#xff0c;我们的消息系统是messaging s…...

linux使用grep命令查询nginx的进程情况时总是出现 grep --color=auto nginx

问题&#xff1a; 每次使用ps aux | grep 服务名 命令查询某个服务的进程时&#xff0c;总会出现一条grep --colorauto 服务名 例如&#xff1a; ps aux | grep nginx # 会出现图片中的情况解答&#xff1a; 这是因为grep 也是一条命令&#xff0c;它在输出时&#xff0c;会…...

FFmpeg音视频开发知识点(二)

系列文章目录 FFmpeg音视频开发知识点&#xff08;一&#xff09; 文章目录 系列文章目录前言一、AAC音频编码1. ffmpeg编译第三方的libfdk_aac2. S16重采样FLTP 二、AAC音频解码总结 前言 该篇讲解一下&#xff0c;音频编解码中的难点&#xff0c;以及开发过程中遇到问题&am…...

【Java可执行命令】(十)JAR文件签名工具 jarsigner:通过数字签名及验证保证代码信任与安全,深入解析 Java的 jarsigner命令~

Java可执行命令之jarsigner 1️⃣ 概念2️⃣ 优势和缺点3️⃣ 使用3.1 语法3.1.1 可选参数&#xff1a;jarsigner -keystore < url>3.1.2 可选参数&#xff1a;jarsigner -storepass <口令>3.1.3 可选参数&#xff1a;jarsigner -keypass <口令>3.1.4 可选参…...