1.学会使用Linux中的码实GCC命令linuxgcc命令
2.Gcode在线模拟器-CNC编程利器
3.gin框架原理详解(gin框架是什么)
4.编译器原理与源码实例讲解:22. 编译器的应用领域与案例分析
5.opengl-01:源码编译
6.游戏引擎随笔 0x20:UE5 Nanite 源码解析之渲染篇:BVH 与 Cluster 的 Culling
学会使用Linux中的GCC命令linuxgcc命令
学会使用Linux中的GCC命令
GCC是GNU编译器套件的缩写,它是码实一个广泛使用的编译器,在Linux操作系统中也被广泛使用。码实GCC命令能够让用户在Linux操作系统上编写C、码实C++、码实java等语言的码实泄露的游戏源码代码,并且进行编译、码实链接、码实优化和生成可执行文件。码实在学习Linux编程或是码实进行开发工作时,学会使用GCC命令是码实非常重要的。
一、码实GCC的码实安装
GCC命令是Linux环境中的一个重要工具,因此,码实安装GCC应该是码实第一步。GCC可直接通过终端命令进行安装,在终端命令行中输入以下命令即可安装GCC:
sudo apt-get install gcc
输入此命令后,Linux操作系统将在本地系统中下载GCC的安装包,然后安装到本地系统上。
二、编写C或C++代码
GCC命令是用来编译C语言或C++语言的代码的。因此,在使用GCC前,需要先编写一段C或C++代码。以下是一个简单的实例代码:
#include
int main() {
printf(“Hello, world!”);
return 0;
}
以上代码是一个基本的Hello World程序,它使用了C语言中的printf函数进行输出。
三、编译C或C++代码
在编写C或C++代码后,需要使用GCC命令进行编译。在终端中,输入以下命令来编译代码:
gcc -o hello hello.c
gcc命令后面的参数-o指定最终生成的可执行文件的名字,hello是指可执行文件的文件名,hello.c是指要编译的源代码文件。输入完上述命令后,hello可执行文件就被生成了。
四、运行可执行文件
在编译代码之后,就可以运行可执行文件了。在终端中,输入以下命令来运行可执行文件:
./hello
以上命令将执行hello可执行文件。 在屏幕上,我们将看到输出的结果:Hello, world!。
五、使用Makefile
如果代码包含多个源文件,手动执行G++,将会非常麻烦。这时,pb源码下使用Makefile会方便很多。
Makefile可以让项目的编译、链接过程自动化,大大提高了效率。
以下是一个简单的Makefile文件:
CC=gcc
CFLAGS=-I.
hello: main.o hello.o
$(CC) -o hello main.o hello.o
main.o: main.c hello.h
$(CC) -c -o main.o main.c $(CFLAGS)
hello.o: hello.c hello.h
$(CC) -c -o hello.o hello.c $(CFLAGS)
clean:
rm -f *.o hello
在目录中,保存为Makefile文件名,然后使用make进行编译。make可以根据Makefile文件自动判断哪些文件需要重新编译,从而完成自动化编译、链接,生成可执行文件。使用make命令,我们可以将上述代码编译成可执行文件hello。
六、调试代码
在使用GCC进行编译时,可以开启-g 参数来生成调试信息。调试信息可以帮助我们更快地定位错误。
在终端中,输入以下命令来生成带有调试信息的可执行文件:
gcc -g -o hello hello.c
七、优化性能
GCC命令还可以用于优化性能。GCC提供了多个优化选项,可以让程序更加高效。以下是一个优化等级的实例:
gcc -O3 -o hello hello.c
以上命令将以最高优化等级进行编译。
总结
以上部分介绍了如何安装、使用GCC命令,在Linux中编写C或C++代码,使用Makefile自动化编译过程,调试代码及使用优化选项来提升程序性能。熟练掌握GCC命令,可以对开发者学习Linux编程、提升编程能力、开发高效应用程序非常有帮助。
Gcode在线模拟器-CNC编程利器
一款强大且便捷的Gcode在线模拟器,成为数控机床CNC编程的利器。您能在这里自行编写G代码,并且还有详尽的示例供您参考,助您快速掌握数控机床编程技巧。
在线地址:数控编程必备书
跟随书本中的Gcode教程,通过逐行编写并添加注释,您能获得最高效的学习体验。这样的方式能让您深入理解Gcode的精髓。
深入探索Gcode,了解其基本命令与用法。以下是一些Gcode实例源代码,它们承载着丰富的schedulerx源码下载信息与功能,但出于格式限制,仅展示部分示例,以节省空间。
gin框架原理详解(gin框架是什么)
Gin的启动过程、路由及上下文源码解读
Engine是gin框架的一个实例,它包含了多路复用器、中间件和配置中心。
gin通过Engine.Run(addr...string)来启动服务,最终调用的是/手败gin-gonic/gin
一个简单的例子:
packagemain
import"github.com/gin-gonic/gin"
funcmain(){
//Default返回一个默认的路由引擎
r:=gin.Default()
r.GET("/ping",func(c*gin.Context){
//输出json结果给调用方
c.JSON(,gin.H{
"message":"pong",
})
})
r.Run()//listenandserveon0.0.0.0:
}
编译运行程序,打开浏览器,访问页面显示:
{ "message":"pong"}
gin的功能不只是简单输出Json数据。它是一个轻量级的WEB框架,支持RestFull风格API,支持GET,POST,PUT,PATCH,DELETE,OPTIONS等/gin-gonic/gin"
)
funcmain(){
router:=gin.Default()
//静态资源加载,本例为css,js以及资源
router.StaticFS("/public",/ffhelicopter/tmm/website/static"))
router.StaticFile("/favicon.ico","./resources/favicon.ico")
//Listenandserveon0.0.0.0:
router.Run(":")
}
首先需要是生成一个Engine,这是gin的核心,默认带有Logger和Recovery两个中间件。
router:=gin.Default()
StaticFile是加载单个文件,而StaticFS是加载一个完整的目录资源:
func(group*RouterGroup)StaticFile(relativePath,filepathstring)IRoutes
func(group*RouterGroup)StaticFS(relativePathstring,fs/gin-gonic/gin
如果安装失败,直接去Githubclone下来,放置到对应的目录即可。
(2)代码中使用:
下面是一个使用Gin的简单例子:
packagemain
import(
"github.com/gin-gonic/gin"
)
funcmain(){
router:=gin.Default()
router.GET("/ping",func(c*gin.Context){
c.JSON(,gin.H{
"message":"pong",
})
})
router.Run(":")//listenandserveon0.0.0.0:
}
简单几行代码,就能实现一个web服务。使用gin的Default方法创建一个路由handler。然后通过HTTP方法绑定路由规则和路由函数。不同于net/e"}。
注:Gin还包含更多的返回方法如c.String,c.HTML,c.XML等,请自行了解。可以方便的返回HTML数据
我们在之前的组v1路由下新定义一个路由:
下面我们访问
可以看到,通过c.Param(“key”)方法,Gin成功捕获了url请求路径中的参数。同理,gin也可以捕获常规参数,如下代码所示:
在浏览器输入以下代码:
通过c.Query(“key”)可以成功接收到url参数,c.DefaultQuery在参数不存在的情况下,会由其默认值代替。
我们还可以为Gin定义一些默认路由:
这时候,我们访问一个不存在的页面:
返回如下所示:
下面我们测试在Gin里面使用Post
在测试端输入:
附带发送的数据,测试即可。记住需要使用POST方法.
继续修改,grafana 源码解读将PostHandler的函数修改如下
测试工具输入:
发送的内容输入:
返回结果如下:
备注:此处需要指定Content-Type为application/x-www-form-urlencoded,否则识别不出来。
一定要选择对应的PUT或者DELETE方法。
Gin框架快速的创建路由
能够方便的创建分组
支持url正则表达式
支持参数查找(c.Paramc.Queryc.PostForm)
请求方法精准匹配
支持处理
快速的返回给客户端数据,常用的c.Stringc.JSONc.Data
编译器原理与源码实例讲解:. 编译器的应用领域与案例分析
编译器是计算机科学领域的重要概念,负责将高级语言转换为计算机可执行的低级代码。编译器广泛应用于软件开发、人工智能、大数据处理等领域。本文将深入探讨编译器的核心概念、算法原理、操作步骤、数学模型、代码实例及未来趋势与挑战。
编译器的核心包括语法分析、语义分析、中间代码生成、优化和目标代码生成等。
语法分析将源代码解析为抽象语法树,语义分析检查代码语义,中间代码生成将语法树转换为抽象中间代码,优化改进中间代码,目标代码生成最终转换为机器可执行代码。
优化策略包括死代码消除、常量折叠、循环不变量分析等,目标代码生成针对特定平台,将中间代码转换为机器代码。
具体代码实例展示了一个简单的计算器程序,演示了编译器的核心功能。
未来,编译器技术将适应新架构、语言和应用场景,如多核、异构计算、跨平台支持等。
常见问题解答包括编译器工作原理、类型、优化技术和面临的挑战。
通过本文,读者可深入理解编译器的各个方面,并对未来发展有全面认识。
opengl-:源码编译
1 源码编译 + cmake + vscode
系统环境:ubuntu ..6
编译环境: g++9.4 cmake3..3
编译工具:vscode
1.1 glfw源码编译
Release 3.3. · glfw/glfw 下载 glfw-3.3..zip
安装依赖
解压源码文件
cmake配置
编译工程 edgelee / vscode-opengl-tutorial -1-glfw
1.2 glad源码编译
glad.dav1d.de/ 选择配置内容(如图)
生成源文件 glad.zip
解压zip
cmake配置
一级CmakeList
二级CmakeList
编译工程 edgelee / vscode-opengl-tutorial -2-glad
1.3 imgui源码编译(依赖系统OpenGL)
imgui源码下载
github.com/ocornut/imgu...
ubuntu安装opengl
解压zip
cmake配置
一级CmakeList
二级CmakeList
根据makefile内容配置CmakeList(imgui-1..4/examples/example_glfw_opengl3/Makefile)
编译输出 edgelee / vscode-opengl-tutorial -3-imgui-(system-gl)
1.4 imgui源码编译(不依赖系统OpenGL)
imgui源码下载:同1.3
ubuntu安装opengl:不需要(即使安装,不使用)
解压zip:同1.3
cmake配置
一级CmakeList:同1.3
二级CmakeList:去掉OpenGL依赖
编译错误
根据错误提示,修正
imgui-1..4/backends/imgui_impl_glfw.cpp文件的味道网站源码添加
编译结果 edgelee / vscode-opengl-tutorial -3-imgui-(no-system-gl)
2 实例2.1 旋转三角形 glfw +glad
源码文件:glfw-3.3./examples/simple.c(不采用glfw自带glad,修改到自编译glad)
一级CmakeList
二级CmakeList
生成效果 edgelee / vscode-opengl-tutorial -sample-glfw-glad
2.2 gui界面 glfw +imgui
源码文件:imgui-1..4/examples/example_glfw_opengl3/main.cpp
一级CmakeList
二级CmakeList
生成效果 edgelee / vscode-opengl-tutorial -sample-glfw-imgui
2.3 gui界面 glfw +glda +imgui(建议方式)
注:建议采用此方式,openGL api 统一使用 gdal api
源码文件:imgui-1..4/examples/example_glfw_opengl3/main.cpp(修改到 gdal api)
一级CmakeList
二级CmakeList
生成效果 edgelee / vscode-opengl-tutorial -sample-glfw-glad-imgui
游戏引擎随笔 0x:UE5 Nanite 源码解析之渲染篇:BVH 与 Cluster 的 Culling
Nanite遵循的设计理念是三角形的绘制数量超过像素数量就是一种浪费。UE5中的Nanite技术在EA版本发布后揭开了面纱,其渲染性能令人惊叹,本文尝试从源码层面解析Nanite的实现技术,详细讲解Nanite的实现细节,以供开发者参考。
Nanite在GPU端流程如下:
1. **Nanite::Streaming**:异步上传Cluster渲染数据,基于上一帧回读的Cluster Page Request数据进行。
2. **Nanite::InitContext**:初始化Culling上下文的GPU相关数据。
3. **Nanite::CullRasterize**:执行剔除与光栅化,包含生成深度目标、执行基础渲染以及生成阴影等步骤。
4. **Nanite::EmitDepthTargets**:根据Visibility Buffer生成深度相关的Buffer,如Scene Depth、Stencil、Velocity、Material Depth等。
5. **Nanite::BasePass**:使用Visibility Buffer和Cluster相关Buffer输出Deferred Rendering所需的G-Buffer。
6. **Nanite Shadows**:生成阴影所需的深度信息,仅包含InitContext和CullRasterize两步。
7. **Nanite::Readback**:回读PersistentCull pass产生的Cluster Page Request数据。
本文重点解析CullRasterize步骤中的PersistentCull pass源码。
为了在GPU上高效执行Culling,Nanite预生成了BVH(Bounding Volume Hierarchy),每个节点最多包含8个子节点,叶节点存储实际的Cluster索引数据。但要在GPU中实现高效的层次遍历且负载均衡并非易事,设计的不合理会导致性能下降、GPU线程闲置。
UE5的Nanite在GPU端实现了一种高效的遍历机制,性能高且负载均衡,GPU在整个过程中几乎满负荷运行。BVH和Cluster数据结构与存储方式都围绕着高效遍历和负载均衡的目标设计。
**关键Buffers数据结构**:
- **CandidateNodesAndClusters**:存储候选BVH Node和Cluster信息的全局Buffer,内存布局包括待处理的Cluster Group总数、所有候选Cluster Packed数据和所有候选BVH Node Packed数据。
- **MainAndPostPassPersistentStates**:存储Culling过程中的状态数据,包括用于写入BVH Node的读写偏移、Cluster读写偏移等。
- **InstanceCull**:执行对象实例级别的可见剔除,将可见的BVH Root Node存储在CandidateNodesAndClusters中。
- **PersistentClusterCull**:充分利用GPU线程,避免空闲,分为Node和Cluster处理两个阶段,通过组内线程同步和多线程并行处理,实现负载均衡。
**BVH Node Culling解析**:
1. 每组线程计算需要处理的候选BVH节点,通过原子操作统计有效节点数量,并在处理完成时切换至Cluster Culling。
2. 通过组内线程索引计算节点和子节点的索引,执行子节点的Culling处理,同时通过队列管理新产生的候选节点。
3. 优化候选Cluster存储,减少GPU Buffer写入开销。
**Cluster Culling解析**:
1. 处理存储在队列中的候选Cluster,通过编码和同步机制查找需要处理的Cluster。
2. 执行真正的Culling逻辑,包括可见性判断、硬件或软件光栅化等。
3. 将可见的Cluster写入全局缓冲,根据光栅化类型顺序存储,并在Post Pass中再次执行Culling流程。
解析至此,UE5的Nanite技术通过高效的GPU算法和数据结构实现了强大的渲染性能,使得百万面的高精度模型在老显卡上也能实现流畅运行。UE5团队的设计与工程实现能力令人敬佩,其精神和勇气引领了行业技术的前沿。通过深入源码学习,开发者可以深入了解先进的设计思想和工程实现方法,提升自己的技术实力。
GDB 简介 调试 使用实例
GNU调试器gdb是Linux系统中不可或缺的工具,它作为字符模式下的交互式调试器,能协助我们深入程序内部进行各种任务。除了gdb,还有一些其他如xxgdb,ddd, kgdb, ups等调试器,但gdb因其强大功能而备受青睐。 gdb的强大功能包括设置断点,监控变量值,单步执行程序,查看和修改变量和寄存器,检查堆栈情况,甚至支持远程调试。要使用gdb,首先需要在编译源代码时添加-g选项以生成调试信息。运行时,通过命令如gdb progname启动调试器,然后通过一系列命令如list、run、break等进行调试。 以下是gdb的一些实用操作实例:在gdb中列出文件清单:(gdb) list line1,line2
执行程序并设置参数:(gdb) run –b –x
查看和修改变量值:(gdb) print p (p为变量名)
设置断点:(gdb) break line-number 或 function-name
断点管理:使用info break查看和管理断点,如删除或启用禁用断点
单步执行:next(不进入函数)和step(进入函数)
信号处理:通过handle命令控制信号的行为
查看源代码:search和reverse-search用于搜索文本
在实际应用中,比如调试buggy.c程序,可以使用gdb的break命令在出错行设置断点,然后通过print命令检查变量值,或者直接修改变量以解决错误。gdb提供了丰富的命令集,如info命令用于获取程序状态,list命令显示源代码段,使得调试过程更为高效。如何用 Flutter 实现混合开发?闲鱼公开源代码实例
阿里妹导读:具有一定规模的 App 通常有一套成熟通用的基础库,尤其是阿里系 App,一般需要依赖很多体系内的基础库。那么使用 Flutter 重新从头开发 App 的成本和风险都较高。所以在 Native App 进行渐进式迁移是 Flutter 技术在现有 Native App 进行应用的稳健型方式。
今天我们来看看,闲鱼团队如何在这个实践过程中沉淀出一套独具特色的混合技术方案。
现状及思考
闲鱼目前采用的混合方案是共享同一个引擎的方案。这个方案基于这样一个事实:任何时候我们最多只能看到一个页面,当然有些特定的场景你可以看到多个 ViewController ,但是这些特殊场景我们这里不讨论。
我们可以这样简单去理解这个方案:我们把共享的 Flutter View 当成一个画布,然后用一个 Native 的容器作为逻辑的页面。每次在打开一个容器的时候我们通过通信机制通知 Flutter View 绘制成当前的逻辑页面,然后将 Flutter View 放到当前容器里面。
这个方案无法支持同时存在多个平级逻辑页面的情况,因为你在页面切换的时候必须从栈顶去操作,无法再保持状态的同时进行平级切换。举个例子:有两个页面A,B,当前B在栈顶。切换到A需要把B从栈顶 Pop 出去,此时B的状态丢失,如果想切回B,我们只能重新打开B之前页面的状态无法维持住。
如在 pop 的过程当中,可能会把 Flutter 官方的 Dialog 进行误杀。而且基于栈的操作我们依赖对 Flutter 框架的一个属性修改,这让这个方案具有了侵入性的特点。
新一代混合技术方案 FlutterBoost
重构计划
在闲鱼推进 Flutter 化过程当中,更加复杂的页面场景逐渐暴露了老方案的局限性和一些问题。所以我们启动了代号 FlutterBoost(向C++ Boost库致敬)的新混合技术方案。这次新的混合方案我们的主要目标有:
跟老方案类似,新的方案还是采用共享引擎的模式实现。主要思路是由 Native 容器 Container 通过消息驱动 Flutter 页面容器 Container,从而达到 Native Container与 Flutter Container 的同步目的。我们希望做到 Flutter 渲染的内容是由 Naitve 容器去驱动的。
简单的理解,我们想做到把 Flutter 容器做成浏览器的感觉。填写一个页面地址,然后由容器去管理页面的绘制。在 Native 侧我们只需要关心如果初始化容器,然后设置容器对应的页面标志即可。
主要概念
Native 层概念
Dart 层概念
关于页面的理解
在 Native 和 Flutter 表示页面的对象和概念是不一致的。在 Native,我们对于页面的概念一般是 ViewController,Activity。而对于 Flutter 我们对于页面的概念是 Widget。我们希望可统一页面的概念,或者说弱化抽象掉 Flutter 本身的 Widget 对应的页面概念。换句话说,当一个 Native 的页面容器存在的时候, FlutteBoost 保证一定会有一个 Widget 作为容器的内容。所以我们在理解和进行路由操作的时候都应该以 Native 的容器为准, Flutter Widget 依赖于 Native 页面容器的状态。
那么在 FlutterBoost 的概念里说到页面的时候,我们指的是 Native 容器和它所附属的 Widget。所有页面路由操作,打开或者关闭页面,实际上都是对 Native 页面容器的直接操作。无论路由请求来自何方,最终都会转发给 Native 去实现路由操作。这也是接入 FlutterBoost 的时候需要实现 Platform 协议的原因。
另一方面,我们无法控制业务代码通过 Flutter 本身的 Navigator 去 push 新的 Widget。对于业务不通过 FlutterBoost 而直接使用 Navigator 操作 Widget 的情况,包括 Dialog 这种非全屏 Widget,我们建议是业务自己负责管理其状态。这种类型 Widget 不属于 FlutterBoost 所定义的页面概念。
理解这里的页面概念,对于理解和使用 FlutterBoost 至关重要。
与老方案主要差别
前面我们提到老方案在 Dart 层维护单个 Navigator 栈结构用于 Widget 的切换。而新的方案则是在 Dart 侧引入了 Container 的概念,不再用栈的结构去维护现有的页面,而是通过扁平化 key-value 映射的形式去维护当前所有的页面,每个页面拥有一个唯一的 id。这种结构很自然的支持了页面的查找和切换,不再受制于栈顶操作的问题,之前的一些由于 pop 导致的问题迎刃而解。也不需要依赖修改 Flutter 源码的形式去进行页面栈操作,去掉了实现的侵入性。
实际上我们引入的 Container 就是 Navigator 的,也就是说一个 Native 的容器对应了一个 Navigator。那这是如何做到的呢?
多 Navigator 的实现
Flutter 在底层提供了让你自定义 Navigator 的接口,我们自己实现了一个管理多个 Navigator 的对象。当前最多只会有一个可见的 Flutter Navigator,这个 Navigator 所包含的页面也就是我们当前可见容器所对应的页面。
Native 容器与 Flutter 容器(Navigator)是一一对应的,生命周期也是同步的。当一个 Native 容器被创建的时候,Flutter 的一个容器也被创建,它们通过相同的 id 关联起来。当 Native 的容器被销毁的时候,Flutter 的容器也被销毁。Flutter 容器的状态是跟随 Native 容器,这也就是我们说的 Native 驱动。由 Manager 统一管理切换当前在屏幕上展示的容器。
我们用一个简单的例子描述一个新页面创建的过程:
这就是一个新页面创建的主要逻辑,销毁和进入后台等操作也类似有 Native 容器事件去进行驱动。
官方提出的混合方案
基本原理
Flutter 技术链主要由 C++ 实现的 Flutter Engine 和 Dart 实现的 Framework 组成(其配套的编译和构建工具我们这里不参与讨论)。Flutter Engine 负责线程管理,Dart VM 状态管理和 Dart 代码加载等工作。而 Dart 代码所实现的 Framework 则是业务接触到的主要 API,诸如 Widget 等概念就是在 Dart 层面 Framework 内容。
一个进程里面最多只会初始化一个 Dart VM。然而一个进程可以有多个 Flutter Engine,多个 Engine 实例共享同一个 Dart VM。
我们来看具体实现,在 iOS 上面每初始化一个 FlutterViewController 就会有一个引擎随之初始化,也就意味着会有新的线程(理论上线程可以复用)去跑 Dart 代码。Android 类似的 Activity 也会有类似的效果。如果你启动多个引擎实例,注意此时Dart VM 依然是共享的,只是不同 Engine 实例加载的代码跑在各自独立的 Isolate。
官方建议
引擎深度共享
在混合方案方面,我们跟 Google 讨论了可能的一些方案。Flutter 官方给出的建议是从长期来看,我们应该支持在同一个引擎支持多窗口绘制的能力,至少在逻辑上做到 FlutterViewController 是共享同一个引擎的资源的。换句话说,我们希望所有绘制窗口共享同一个主 Isolate。
但官方给出的长期建议目前来说没有很好的支持。
多引擎模式
我们在混合方案中解决的主要问题是如何去处理交替出现的 Flutter 和 Native 页面。Google 工程师给出了一个 Keep It Simple 的方案:对于连续的 Flutter 页面(Widget)只需要在当前 FlutterViewController 打开即可,对于间隔的 Flutter 页面我们初始化新的引擎。
例如,我们进行下面一组导航操作:
我们只需要在 Flutter Page1 和 Flutter Page3 创建不同的 Flutter 实例即可。
这个方案的好处就是简单易懂,逻辑清晰,但是也有潜在的问题。如果一个 Native 页面一个 Flutter 页面一直交替进行的话,Flutter Engine 的数量会线性增加,而 Flutter Engine 本身是一个比较重的对象。
多引擎模式的问题
因此,综合多方面考虑,我们没有采用多引擎混合方案。
总结
目前 FlutterBoost 已经在生产环境支撑着在闲鱼客户端中所有的基于 Flutter 开发业务,为更加负复杂的混合场景提供了支持,稳定为亿级用户提供服务。
我们在项目启动之初就希望 FlutterBoost 能够解决 Native App 混合模式接入 Flutter 这个通用问题。所以我们把它做成了一个可复用的 Flutter 插件,希望吸引更多感兴趣的朋友参与到 Flutter 社区的建设。在有限篇幅中,我们分享了闲鱼在 Flutter 混合技术方案中积累的经验和代码。欢迎兴趣的同学能够积极与我们一起交流学习。
扩展补充
在两个 Flutter 页面进行切换的时候,因为我们只有一个 Flutter View 所以需要对上一个页面进行截图保存,如果 Flutter 页面多截图会占用大量内存。这里我们采用文件内存二级缓存策略,在内存中最多只保存 2-3 个截图,其余的写入文件按需加载。这样我们可以在保证用户体验的同时在内存方面也保持一个较为稳定的水平。
页面渲染性能方面,Flutter 的 AOT 优势展露无遗。在页面快速切换的时候,Flutter 能够很灵敏的响应页面的切换,在逻辑上创造出一种 Flutter 多个页面的感觉。
项目开始的时候我们基于闲鱼目前使用的 Flutter 版本进行开发,而后进行了 Release 1.0 兼容升级测试目前没有发现问题。
只要是集成了 Flutter 的项目都可以用官方依赖的方式非常方便的以插件形式引入 FlutterBoost,只需要对工程进行少量代码接入即可完成接入。详细接入文档,请参阅 GitHub 主页官方项目文档。