Flutter 正在推进全新 PlatformView 实现 HCPP, 它又用到了 Android 上的什么黑科技
跨平台开发里的 PlatformView 实现一直是一个经久不衰的话题,在之前的 《深入 Flutter 和 Compose 的 PlatformView 实现对比》 我们就详细聊过 Flutter 和 Compose 在 PlatformView 实现上的异同之处,也聊到了 Compose 为什么在相同实现上对比 Flutter 会更有优势的原因。
那么随着 3.29 的发布,恰好关注到其实 Flutter 在 Android 的 PlatformView 上其实正在落地另外一种实现,而这种实现目前看来可以做到在 HC 的基础上得到更好的性能,所以也被暂时称为 HCPP。
在聊 HCPP 之前我们再简单回顾下 Flutter 在 Android 上的 PlatformView 实现模式:
- VD:最老的实现模式,利用副屏
VirtualDisplay
的相关支持在内存实现原生控件的模拟绘制和纹理提取 - HC:通过直接将原生控件 add 到
FlutterView
上,然后通过新的FlutterImageView
提供新的 Surface 来实现控件 UI 堆叠合成 - TLHC:还是直接将原生控件 add 到
FlutterView
上,但是中间利用通过 parent 替代掉 child 的 canvas,让原生控件绘制的对应的surface.lockHardwareCanvas
上
有点抽象?,没关系,后面有简单的直观例子。
在这个过程中几种模式各有优劣,比如:
- TLHC 模式不支持
SurfaceView
等控件,因为SurfaceView
有自己独立的 Surface 和 Canva ,它的 Surface 直接来自SurfaceFlinger
,也就是当前 Window 下 - TLHC 模式与异步更新 View 一起使用时(如 TextureView 或基于 GL 的渲染器),需要在更新内容时在对应 PlatformView 显式调用
invalidate
才能保证正确渲染,例如textureView
的onSurfaceTextureUpdated
调用mapView.invalidate
- HC 模式因为不同 API 版本和线程问题,会有同步和额外的性能开销
- ····
所以目前这三种模式是协同工作,例如:
-
initAndroidView
: 默认会使用最新的模式,目前就是 TLHC,如果遇到不支持的就降级到 VD -
initSurfaceAndroidView
: 默认会使用最新的模,目前就是 TLHC,如果遇到不支持的就降级到 HC -
initExpensiveAndroidView
:直接强制使用 HC 模式
那么,回到本次的主题 ,针对全新的 HCPP 实现,Flutter 提供了全新的 API initHybridAndroidView
,可以看到,它需要 Vulkan 和 API 34 的环境才支持使用,如果从这点看,它的通用性又相对较低:
那为什么它需要 API 34 呢?这和它直接使用 SurfaceControl
的 API 逻辑有很大关系,另外,从 Engine 的判断逻辑上可以看到,目前除了判断 Vulkan 和 API 之后,还需要配置对应的 EnableSurfaceControl
才可以测试 HCPP,也就是在 AndroidManifest
增加:
<meta-dataandroid:name="io.flutter.embedding.android.EnableSurfaceControl"android:value="true" />
接着就让我们来看看 HCPP 和其他几种模式有什么区别,其实主要就是和 HC 和 TLHC 进行比较,这里首先做一个容器 Demo ,主要是通过混合 Flutter 和原生控件的效果来区分它们的实现,让 platformView
渲染在两个 Flutter Widget 之间:
return MaterialApp(debugShowCheckedModeBanner: false,home: Stack(alignment: AlignmentDirectional.center,children: <Widget>[///200x200的绿色 Flutter 方块TextButton(key: const ValueKey<String>('AddOverlay'),onPressed: _togglePlatformView,child: const SizedBox(width: 190, height: 190, child: ColoredBox(color: Colors.green)),),///200x200的原生控件,这里用的是一个红色的原生方块if (showPlatformView) ...<Widget>[SizedBox(width: 200, height: 200, child: widget.platformView),///黄色 Flutter 条TextButton(key: const ValueKey<String>('RemoveOverlay'),onPressed: _togglePlatformView,child: const SizedBox(width: 800,height: 25,child: ColoredBox(color: Colors.yellow),),),],],),
);
之后我们可以通过 initExpensiveAndroidView
强制 PlatformView 使用 HC 模式,可以看到,在 HC 模式下出现很多经典的原生层,特别是多了 FlutterImageView
的转换还有它的子类 PlatformOverlayView
:
我们通过 3D 图可以看到,红色的原生 BoxPlatformView
正常被渲染,然后在其之上的 Flutter 控件(一部分黄色条),是通过 FlutterImageView
的子类 PlatformOverlayView
提供的 Surface 独立渲染:
然后我们再通过 initAndroidView
来使用 TLHC 模式,可以看到此时是通过 PlatformViewWrapper
这个 parent 作为容器来承载,而 PlatformViewWrapper
会替换掉原生 BoxPlatformView
的 Canvas,让原生控件的内容渲染到指定 Surface 上 :
我们通过原生 3D 图可以看到,此时的 BoxPlatformView
其实在原生层并没有绘制任何东西,因为其 Canvas 是被替换到内存的 SurfaceTexture
上:
说到 SurfaceTexture
,这个插个题外话,对于 THLC 和 VD 而言,现在创建纹理时是会根据 Android API 来使用不同实现,其中 SurfaceProducer
比较特殊:
因为在此之前,Android 上的 Flutter 引擎支持两个外部渲染源:SurfaceTexture (OpenGLES 纹理)和 ImageReader(GPU-ready buffer),其中 Image.getHardwareBuffer
需要 API 28 支持。
而为了适配 Impeller 团队提出了 SurfaceProducer
概念,让 Android 在运行时选择“最佳”渲染 Surface,除了 PlatformView 场景,在外界纹理场景也需要适配的情况:
- TextureRegistry.SurfaceTextureEntry entry = textureRegistry.createSurfaceTexture();
+ TextureRegistry.SurfaceProducer producer = textureRegistry.createSurfaceProducer();- Surface surface = new Surface(entry.surfaceTexture());
+ Surface surface = producer.getSurface();
那么我们看 HCPP,通过 initHybridAndroidView
我们启用了 HCPP 模式,可以看到,此时 UI 的层级结构类似 TLHC, 但是 parent 使用的是 HC 模式中的 FlutterMutatorView
:
然后我们看 3D 效果,原生控件 BoxPlatformView
其实可以被完整被渲染,证明其 Canvas 并没有被替代,那么这里就有一个神奇的问题了:Flutter 的黄色控件,是如何渲染到红色的 BoxPlatformView
之上的?
这就不得不提 PlatformViewsController2
,作为一个 HCPP 的临时对象,它的实现里有一个关键的对象 SurfaceControl
,并且在事务提交时通过 setLayer
设置了 z 轴为 1000
:
我们可以看提交更改里,基本上全新的 PlatformViewsController2
核心逻辑都在于操作 SurfaceControl
:
在 Android 里,SurfaceControl
是一种用于管理和操作与显示系统相关的图形资源的类,简单说就是与 Surface
相关的操作,SurfaceControl
可以用于创建和管理 Surface
,它是和SurfaceFlinger
交互的一个主要接口,交互的方式则是通过 Transaction
。
而在 HCPP 里,我们可以看到,此时的 Surface
正是通过一个全新的 SurfaceControl
创建得到,而这个 SurfaceControl
的 Transaction
来自 FlutterView
:
也就是,在 HCPP 模式里,Flutter 通过 SurfaceControl.Transaction
构造了一个全新的 Surface
用于 SurfaceFlinger
合成,并且还通过 setLayer
将 Surface 的 z 轴设置到了 1000 ,而这个 1000 就是黄色 Flutter 控件可以渲染到原生红色方块之上的原因。
举个例子,我们将 SurfaceControl
这部分代码复制到一个简单的纯原生项目里,并且同样对创建的 Surface
设置 1000 和绘制红色:
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);········// 获取 FrameLayoutFrameLayout rootView = findViewById(R.id.container);rootView.postDelayed(new Runnable() {@Overridepublic void run() {final SurfaceControl.Builder surfaceControlBuilder = new SurfaceControl.Builder();surfaceControlBuilder.setBufferSize(500, 500);surfaceControlBuilder.setFormat(PixelFormat.RGBA_8888);surfaceControlBuilder.setName("Flutter Overlay Surface");surfaceControlBuilder.setOpaque(false);surfaceControlBuilder.setHidden(false);final SurfaceControl surfaceControl = surfaceControlBuilder.build();final SurfaceControl.Transaction tx =binding.container.getRootSurfaceControl().buildReparentTransaction(surfaceControl);tx.setLayer(surfaceControl, 1000);tx.apply();surface1 = new Surface(surfaceControl);surfaceControl1 = surfaceControl;// 在 SurfaceView 上绘制一些内容drawOnSurface(surface1, Color.RED); }}, 2000);}private void drawOnSurface(Surface surface, int color) {Canvas canvas = surface.lockCanvas(null);if (canvas != null) {canvas.drawColor(color);surface.unlockCanvasAndPost(canvas);}
}
然后我们看最终绘制的效果,可以看到绿色背景的 FrameLayout
是在 WebView
下方的,但是通过 container.getRootSurfaceControl()
创建的 Surface
因为 z 轴为 1000 的原因,最终红色方块会绘制到 WebView
之上:
另外,在目前逻辑中,Engine 如果判断当前帧如果不存在 PlatformView ,并且上一帧存在 PlatformView,那么就会调用 hideOverlaySurface2
从而直接触发 Java 层面的 platformViewsController2.hideOverlaySurface()
,进而隐藏不需要的 Layer :
if (!FrameHasPlatformLayers()) {frame->Submit();// If the previous frame had platform views, hide the overlay surface.if (previous_frame_view_count_ > 0) {jni_facade_->hideOverlaySurface2();}jni_facade_->applyTransaction();return;}
所以可以看到,HCPP 主要就是通过 SurfaceControl
来构造一个高层级的 Surface
从而实现最终绘制时混合覆盖的问题,这和我们之前聊 《深入 Flutter 和 Compose 的 PlatformView 实现对比》 里 Compose 可以在 PlatformView 里直接使用 SurfaceView
的道理类似,都是 SurfaceFlinger
合成时的层级操作。
至于为什么需要 API 34, 主要也是 SurfaceControl 对应的一些 API 需要的版本都很高,另外我依稀记得, Android 14 在通过 SurfaceControl 实现低延迟绘图时,可以更好支持 Canvas API 通过硬件加速绘制到 HardwareBuffer :
如果对于 Engine 部份逻辑感兴趣的,也可以看 external_view_embedder_2#SubmitFlutterView
这部分逻辑里如何通过 GetLayer 去创建 FlutterOverlaySurface
。
目前 HCPP 还处于 main 分之的 beta 状态,如果后续正式落地,那对于 Android PlatformView 实现将会是存在 4 种组合模式,相比较 iOS 端多个 CALayer 的合成模式,Android 的 PlatformView 可以说是一路坎坷至今。
最后,你觉得 HCPP 会成为落地为全新的 PlatformView 支持吗?
PS :
io.flutter.embedding.android.EnableSurfaceControl
标识还用于控制 Impeller 内部使用 Vulkan swapchain 或者 Android SurfaceControl (AHB swapchain),在 Android SurfaceControl 模式下,Java 端创建的 Transaction 会链接到 AHB swapchain。当然, AHBSwapchainVK 交换链实现并非在所有 Android 版本上都可用,一般不支持的话,会回退到 KHR swapchain。
参考链接
-
https://github.com/flutter/flutter/issues/163073
-
https://github.com/flutter/flutter/pull/161829
-
https://github.com/flutter/flutter/issues/144184
相关文章:
Flutter 正在推进全新 PlatformView 实现 HCPP, 它又用到了 Android 上的什么黑科技
跨平台开发里的 PlatformView 实现一直是一个经久不衰的话题,在之前的 《深入 Flutter 和 Compose 的 PlatformView 实现对比》 我们就详细聊过 Flutter 和 Compose 在 PlatformView 实现上的异同之处,也聊到了 Compose 为什么在相同实现上对比 Flutter …...
VAS1260IB05E 集成内部开关驱动器的汽车级LED硬灯带高效解决方案
VAS1260IB05E LED芯片是一种连续模式电感降压转换器,设计用于从高于LED电压的电压源高效驱动单个或多个串联连接的LED。该设备在5V至60V之间的输入电源下工作,并提供高达1.2A的外部可调输出电流。包括输出开关和高侧输出电流感测电路,该电路使…...
5.【线性代数】—— 转置,置换和向量空间
五 转置,置换和向量空间 1. 置换矩阵2. 转置矩阵3. 对称矩阵4. 向量空间4.1 向量空间4.2 子空间 1. 置换矩阵 定义: 用于行互换的矩阵P。 之前进行ALU分解时,可能存在该行主元为0,要进行行互换,即PALU 性质࿱…...
前端如何实现一个五星评价,鼠标滑动,前边星星颜色的变黄,后边的不变;
直接上代码 <!DOCTYPE html> <html> <head> <style> .star-rating {display: flex;padding: 10px 0; }.star {position: relative;width: 40px;height: 40px; }.half {position: absolute;top: 0;width: 20px;height: 40px;overflow: hidden;font-siz…...
等差数列有几项--INT_MAX【#include <climits>】
等差数列 题目代码INT_MAX的使用 题目 代码 #include <iostream> #include <vector> #include <string> #include <algorithm> #include <math.h> #include <queue> #include <climits> // 包含INT_MAX常量 #include <cctype&g…...
Linux /dev/null
/dev/null 是 Linux 和类 Unix 系统中一个特殊且非常有用的设备文件,也被称为空设备。下面为你详细介绍它的特点、用途和使用示例。 特点 写入丢弃:当向 /dev/null 写入数据时,这些数据会被立即丢弃,不会被保存到任何地方&#…...
计算机视觉-尺度不变区域
一、尺度不变性 1.1 尺度不变性 找到一个函数,实现尺度的选择特性。 1.2 高斯偏导模版求边缘 1.3 高斯二阶导 用二阶过零点检测边缘 高斯二阶导有两个参数:方差和窗宽(给定方差可以算出窗宽) 当图像与二阶导高斯滤波核能匹配…...
串的基本操作--数据结构
目录 一、串的基本概述 二、串的存储结构 2.1定义属性存储结构 串长有两种表示方法: 1、用一个额外的变量length来存放串的长度; 2、串值后面加一个不计入串长的结束标记字符“\0”,此时的串长为隐含值。 2.2堆的顺序存储结构 三、串的基本操…...
C++17 数学特殊函数:探索标准库中的强大工具
文章目录 1. 什么是数学特殊函数?2. C17 中的特殊函数2.1 贝塞尔函数2.2 勒让德函数2.3 椭圆积分2.4 伽马函数2.5 误差函数 3. 实际应用场景3.1 科学计算3.2 工程应用3.3 数据分析 4. 总结 在 C17 中,标准库引入了一系列数学特殊函数,这些函数…...
多模态特征提取与融合助力高光谱+LiDAR数据分类性能飞跃
目录 论文解读 总体架构 CMIIE 模块工作模式 MLFFC模块工作模式 论文解读 提出了一种新的多模态特征提取模块CMIIE,可以捕获高光谱和LiDAR数据之间的互补信息。设计了一个多层特征融合分类模块MLFFC,通过对不同层级的特征进行融合来提高分类性能。使用对抗学习策略来指导网…...
内容中台重构企业内容管理流程驱动智能协作升级
内容概要 内容中台作为企业数字化转型的核心基础设施,通过技术架构革新与功能模块整合,重构了传统内容管理流程的底层逻辑。其核心价值在于构建动态化、智能化的内容生产与流转体系,将分散的创作、存储、审核及分发环节纳入统一平台管理。基…...
网络安全攻防演练——RT实战技巧篇
前言 又是一年hw招聘季,每年hw行动都会吸引大量网络安全从业者参加。同时也会有很多热爱网络安全但无从下手的网安爱好者参与。笔者旨在对网络安全有想法但是没有方向的师傅做一个简单的方向的了解,让师傅有方向去学习。 RT(红队) 1.引入 首先红队的…...
【MySQL】第六弹---数据库表约束详解:从空属性到主键的全方位指南
✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】【MySQL】 目录 1. 表的约束 1.1 空属性 1.2 默认值 1.3 列描述 1.4 zerofill 1.5 主键 1. 表的约束 真正约束字段的是数据类型&…...
JMeter工具介绍、元件和组件的介绍
Jmeter功能概要 JDK常用文件目录介绍 Bin目录:存放可执行文件和配置文件 Docs目录:是Jmeter的API文档,用于开发扩展组件 printable_docs目录:用户帮助手册 lib目录:存放JMeter依赖的jar包和用户扩展所依赖的Jar包…...
vue3 在element-plus表格使用render-header
在vue2中 element表格render-header 源码是有返回h()函数的 在vue3 element-plus 表格源码 render-header函数没有返回h函数了 所以需要用render-header方法中创建虚拟DOM节点的话需要引用h方法 <el-table-column header-align"right" align"right" …...
IM 即时通讯系统-04-聊一聊 IM 要如何进行技术选型
IM 系列 IM 文档开源库 首先,后端技术选型是Java。Java有很多优势,比如跨平台性、丰富的生态系统、高性能和成熟稳定。这些都是为什么选择Java的原因。接下来,前端选用了Vue,因为它具有渐进式框架的特点、响应式数据绑定、组件化…...
机器学习_19 集成学习知识点总结
集成学习(Ensemble Learning)是一种强大的机器学习范式,通过组合多个模型的预测结果来提高整体性能和泛化能力。它在分类、回归和特征选择等任务中表现出色,广泛应用于各种实际问题。今天,我们就来深入探讨集成学习的原…...
自动驾驶---基于深度学习模型的轨迹预测
1 背景 自动驾驶任务中,轨迹预测一直以来是一个难题。 在复杂交通场景中,即使驾驶员最终意图确定,但决策过程中其他车辆的动态行驶路径的即时变化会导致自车路径呈现多模态属性,即车辆的未来轨迹有多种可能性。对车辆的多模态轨迹…...
线性模型 - 二分类问题的损失函数
在二分类问题中,损失函数用于量化模型预测与真实标签之间的差异,以指导模型参数的调整。本文,我们来一起学习一下常见的损失函数及其直观解释。 一、核心二分类损失函数及通俗理解 1. 0-1损失(Zero-One Loss) 公式&…...
string类详解(上)
文章目录 目录1. STL简介1.1 什么是STL1.2 STL的版本1.3 STL的六大组件 2. 为什么学习string类3. 标准库中的string类3.1 string类3.2 string类的常用接口说明 目录 STL简介为什么学习string类标准库中的string类string类的模拟实现现代版写法的String类写时拷贝 1. STL简介 …...
c# —— StringBuilder 类
StringBuilder 类是 C# 和其他一些基于 .NET Framework 的编程语言中的一个类,它位于 System.Text 命名空间下。StringBuilder 类表示一个可变的字符序列,它是为了提供一种比直接使用字符串连接操作更加高效的方式来构建或修改字符串。 与 C# 中的 stri…...
今日行情明日机会——20250217
2025年02月17日行情 后续投资机会分析 根据最新盘面信息,以下板块和个股具备潜在投资机会,需结合市场动态和基本面进一步验证: 1. 腾讯系AI(18家涨停) 核心逻辑:涨停家数最多(18家࿰…...
Openshift或者K8S上部署xxl-job
本案例以版本2.3.0为例 1. 源码编译成jar包 source code: https://github.com/xuxueli/xxl-job/blob/2.3.0/ 这里我们会得到两个jar包:xxl-job-admin-2.3.0.jar和xxl-job-executor-sample-springboot-2.3.0.jar 2. 初始化mysql数据库 sql code: https://github.…...
vite+vue3开发uni-app时低版本浏览器不支持es6语法的问题排坑笔记
重要提示:请首先完整阅读完文章内容后再操作,以免不必要的时间浪费!切记!!!在使用vitevue3开发uni-app项目时,存在低版本浏览器不兼容es6语法的问题,如“?.” “??” 等。为了方便…...
使用 Apache PDFBox 提取 PDF 中的文本和图像
在许多应用中,我们需要从 PDF 文件中提取文本内容和嵌入的图像。为了实现这一目标,Apache PDFBox 是一个非常实用的开源工具库。它提供了丰富的 API,可以帮助我们轻松地读取 PDF 文件、提取其中的文本、图像以及其他资源。 本文将介绍如何使…...
centos7arm架构安装mysql服务
1.安装新版mysql前,需将系统自带的mariadb卸载 rpm -qa|grep mariadb //查找mariadb的rpm包 rpm -e mariadb-libs-5.5.56-2.el7.x86_64 //卸载mariadb包 2.去官网下载对应mysq包https://downloads.mysql.com/archives/community/ 3.解压下载包&…...
【个人开发】deepspeed+Llama-factory 本地数据多卡Lora微调
文章目录 1.背景2.微调方式2.1 关键环境版本信息2.2 步骤2.2.1 下载llama-factory2.2.2 准备数据集2.2.3 微调模式2.2.3.1 zero-3微调2.2.3.2 zero-2微调2.2.3.3 单卡Lora微调 2.3 踩坑经验2.3.1 问题一:ValueError: Undefined dataset xxxx in dataset_info.json.2…...
后端生成二维码,前端请求接口生成二维码并展示,且多个参数后边的参数没有正常传输问题处理
一、后端代码 1、controller GetMapping("/generateQRCode/{url}")ApiOperation(value "生成url链接二维码",notes "生成url链接二维码")public JsonResult<NewsQRCodeVo> generateQRCode(PathVariable String url,HttpServletRespons…...
NBT群落物种级丰度鉴定新方法sylph
文章目录 简介为什么选择Sylph?Sylph的工作原理 Install使用解析成gtdb格式sylph 能做什么?sylph 不能做什么?ANI定义如何使用 sylph-utils 生成包含分类信息的配置文件耗时:66个样本耗时1h 转成easymicroplot可用数据 简介 Sylp…...
长视频生成、尝试性检索、任务推理 | Big Model Weekly 第56期
点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入! 01 COMAL:AConvergent Meta-Algorithm for Aligning LLMs with General Preferences 许多对齐方法,包括基于人类反馈的强化学习(RLHF),依赖于布拉德利-特里&#…...
使用右侧值现象来处理一个word导入登记表的需求
需求也简单,导word文件用户登记表,有各部门的十几个版本(为什么这么多?不知道)。这里说下谈下我的一些代码做法: 需求分析: 如果能解决java字段和各项填的值怎么配对的问题,那么就…...
FRRouting配置与OSPF介绍,配置,命令,bfd算法:
文章目录 1、frrouting的配置:2、ospf2.1、检测和维护邻居关系2.2、ospfDR和BDR2.3、odpf邻居表2.4、ospf常用命令2.5、bfd配置 1、frrouting的配置: sudo service zebra start sudo service ospfd start telnet localhost 2604 en configure termina…...
基于ThinkPHP 5~8兼容的推荐算法类实现,
在现代推荐系统中,随着用户量和物品量的增长,传统的推荐算法可能会面临性能瓶颈。本文将介绍如何基于 ThinkPHP 实现一个高性能的推荐系统,结合显性反馈(如兴趣选择)、隐性反馈(如观看时长、评论、点赞、搜…...
使用Python爬虫实时监控行业新闻案例
目录 背景环境准备请求网页数据解析网页数据定时任务综合代码使用代理IP提升稳定性运行截图与完整代码总结 在互联网时代,新闻的实时性和时效性变得尤为重要。很多行业、技术、商业等领域的新闻都可以为公司或者个人发展提供有价值的信息。如果你有一项需求是要实时…...
kong身份认证插件详解之Basic Auth插件
1.3、Basic Authentication 支持基于用户名和密码的基本认证,通常用于简单的身份验证场景。 1.3.1、环境准备 1.3.1.1、创建一个服务,basic-auth-service curl -i -s -X POST http://localhost:8001/services \--data namebasic-auth-service \--dat…...
Copilot基于企业PPT模板生成演示文稿
关于copilot创建PPT,咱们写过较多文章了: Copilot for PowerPoint通过文件创建PPT Copilot如何将word文稿一键转为PPT Copilot一键将PDF转为PPT,治好了我的精神内耗 测评Copilot和ChatGPT-4o从PDF创建PPT功能 Copilot for PPT全新功能&a…...
用React实现一个登录界面
使用React来创建一个简单的登录表单。以下是一个基本的React登录界面示例: 1. 设置React项目 如果你还没有一个React项目,你可以使用Create React App来创建一个。按照之前的步骤安装Create React App,然后创建一个新项目。 2. 创建登录组…...
前端布局的方式有哪些
前端布局的方式有哪些 在前端开发里,布局就像是装修房子,把不同的东西合理地摆放在合适的位置,让整个空间既美观又实用。下面给你介绍几种常见的前端布局方式: 1. 普通流布局(标准文档流布局) 这就像是按…...
seata集成nacos
#nacos集成nacos并配置mysql数据源 1. 所需依赖 <!--seata 分布式事务--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-seata</artifactId></dependency> 2. 打开seata目录ÿ…...
第29篇 基于ARM A9处理器用C语言实现中断<五>
Q:怎样设计基于ARM A9处理器的C语言程序使用定时器中断实现实时时钟? A:在上一期的程序中添加A9 Private Timer作为第三个中断源,配置该定时器使其每隔0.01秒产生一次中断。使用该定时器使全局变量time的值递增,并将…...
deepseek多列数据对比,联想到excel的高级筛选功能
目录 1 业务背景 2 deepseek提示词输入 3 联想分析 4 EXCEL高级搜索 1 业务背景 系统上线的时候经常会遇到一个问题,系统导入的数据和线下的EXCEL数据是否一致,如果不一致,如何快速找到差异值,原来脑海第一反应就是使用公…...
C 程序多线程拆分文件
C 程序多线程拆分文件 在C语言中,实现多线程来拆分文件通常需要借助多线程库,比如 POSIX 线程库(pthread)或者 Windows 的线程库(CreateThread 或类似的函数)。下面我将分别展示在 Linux 和 Windows 环境下…...
mysql 使用 CONCAT、GROUP_CONCAT 嵌套查询出 json 格式数据
tb_factory表由 factory_code 和 factory_name 字段,查询出如下所示效果: {"factory_0001": "工厂1","factory_0002": "工厂2",... } select sql: SELECT CONCAT( "{",GROUP_CONCAT( C…...
Leetcode 2466. Count Ways To Build Good Strings
Problem Given the integers zero, one, low, and high, we can construct a string by starting with an empty string, and then at each step perform either of the following: Append the character ‘0’ zero times.Append the character ‘1’ one times. This can …...
分布式 IO 模块:食品罐装产线自动化与高效运行的推手
在当今竞争激烈的罐装视频生产行业,如何实现产线的自动化与连续性高效运行,成为了众多企业追求的核心目标。明达技术推出的MR30分布式 IO 模块作为一种先进的工业控制技术,正逐渐崭露头角,为食品罐装产线带来了前所未有的变革。 痛…...
rustdesk编译修改名字
最近,我用Rust重写了一个2W行C代码的linux内核模块。在此记录一点经验。我此前没写过内核模块,认识比较疏浅,有错误欢迎指正。 为什么要重写? 这个模块2W行代码量看起来不多,却在线上时常故障,永远改不完。…...
MySQL 窗口函数:功能、使用场景与性能优化
MySQL 8.0 引入了一个强大的新特性——**窗口函数(Window Functions)**。它为数据分析和复杂查询提供了极大的便利,但同时也可能带来性能问题。本文将带你快速了解窗口函数的功能、使用场景以及如何优化性能。 --- ## **什么是窗口函数&#…...
数据权限校验实践
数据权限控制实践 最近在实习中为公司项目完成一个文件数据权限校验代码的转换重构,写这篇博客来记录前后两种权限校验的实现方案与相关概念 原实现方案:RBAC-基于角色的访问控制 RBAC(Role-Based Access Control) RBAC 是一种常…...
spring boot对接clerk 实现用户信息获取
在现代Web应用中,用户身份验证和管理是一个关键的功能。Clerk是一个提供身份验证和用户管理的服务,可以帮助开发者快速集成这些功能。在本文中,我们将介绍如何使用Spring Boot对接Clerk,以实现用户信息的获取。 1.介绍 Clerk提供…...
公网远程家里局域网电脑过程详细记录,包含设置路由器。
由于从校内迁居小区,校内需要远程控制访问小区内个人电脑,于是早些时间刚好自己是电信宽带,可以申请公网ipv4不需要花钱,所以就打电话直接申请即可,申请成功后访问光猫设备管理界面192.168.1.1,输入用户名密码登录超管(密码是网上查下就有了)设置了光猫为桥接模式,然后…...