文章目录
-
-
-
- [1. BuildOwner,PiplineOwner,SemanticsOwner](#1. BuildOwner,PiplineOwner,SemanticsOwner)
-
- [1.1 BuildOwner 管理Element树](#1.1 BuildOwner 管理Element树)
- [2.2 PipelineOwner 管理RenderObject树](#2.2 PipelineOwner 管理RenderObject树)
- [3.3 SemanticsOwner 管理语义树的](#3.3 SemanticsOwner 管理语义树的)
- [2. Binding](#2. Binding)
-
- [2.1 WidgetsBinding Widget生命周期管理](#2.1 WidgetsBinding Widget生命周期管理)
- [2.2 ServicesBinding - 平台服务通信](#2.2 ServicesBinding - 平台服务通信)
- [2.3 SchedulerBinding - 帧调度和任务管理](#2.3 SchedulerBinding - 帧调度和任务管理)
- [2.4 GestureBinding - 手势事件处理](#2.4 GestureBinding - 手势事件处理)
- [2.5 RendererBinding - 渲染管理](#2.5 RendererBinding - 渲染管理)
- [2.6 SemanticsBinding - 无障碍功能](#2.6 SemanticsBinding - 无障碍功能)
- [2.7 PaintingBinding 图像绘制和解码](#2.7 PaintingBinding 图像绘制和解码)
- setState
- drawFrame方法什么时候调用
-
- [1. 最顶层触发:VSync 信号](#1. 最顶层触发:VSync 信号)
- [2. 什么时候调用](#2. 什么时候调用)
-
-
1. BuildOwner,PiplineOwner,SemanticsOwner
1.1 BuildOwner 管理Element树
dart
class BuildOwner {
final List<Element> _dirtyElements = <Element>[];
void scheduleBuildFor(Element element) {
if (!_dirtyElements.contains(element))
_dirtyElements.add(element);
}
void buildScope(Element context) {
// 重建dirty elements
_dirtyElements.forEach((element) {
// 调用 element的performRebuild(); 触发新的Widget build
element.rebuild();
});
// 重建可能导致RenderObject需要更新
}
}
2.2 PipelineOwner 管理RenderObject树
dart
class PipelineOwner {
final List<RenderObject> _nodesNeedingLayout = <RenderObject>[];
final List<RenderObject> _nodesNeedingPaint = <RenderObject>[];
void requestVisualUpdate() {
// 处理重绘请求
}
void flushLayout() {
// 处理布局
while (_nodesNeedingLayout.isNotEmpty) {
// 执行布局计算
}
}
void flushPaint() {
// 处理绘制
while (_nodesNeedingPaint.isNotEmpty) {
// 执行绘制操作
}
}
}
3.3 SemanticsOwner 管理语义树的
dart
class SemanticsOwner {
final Map<int, SemanticsNode> _nodes = <int, SemanticsNode>{};
void updateSemantics() {
// 更新语义信息
}
}
2. Binding
2.1 WidgetsBinding Widget生命周期管理
dart
class WidgetsBinding {
//管理生命周期
void addObserver(WidgetsBindingObserver observer) => _observers.add(observer);
void drawFrame() {
try {
// 1. 处理UI重建
buildOwner.buildScope(renderViewElement);
// 2. 处理布局绘制
pipelineOwner
..flushLayout()
..flushCompositingBits()
..flushPaint();
// 3. 渲染到屏幕
renderView.compositeFrame();
// 4. 处理语义
_semanticsHandle?.update();
} finally {
// ...
}
}
}
2.2 ServicesBinding - 平台服务通信
dart
// 注册平台消息处理器
// 处理从平台发来的消息
// 发送消息到平台
late final BinaryMessenger _defaultBinaryMessenger;
class ServicesBindingExample {
void demonstrateServicesBinding() {
// 注册平台消息处理器
ServicesBinding.instance.defaultBinaryMessenger.setMessageHandler(
'custom_channel',
(ByteData? message) async {
// 处理从平台发来的消息
if (message != null) {
String data = const StandardMessageCodec().decodeMessage(message);
print('Received from platform: $data');
}
return null;
}
);
// 发送消息到平台
const StandardMethodCodec codec = StandardMethodCodec();
ServicesBinding.instance.defaultBinaryMessenger.send(
'platform_channel',
codec.encodeMethodCall(
MethodCall('someMethod', {'key': 'value'})
)
);
}
}
2.3 SchedulerBinding - 帧调度和任务管理
dart
class SchedulerBindingExample {
void demonstrateSchedulerBinding() {
// 添加帧回调
SchedulerBinding.instance.addPostFrameCallback((_) {
print('Frame rendering completed');
});
// 添加持久性帧回调
SchedulerBinding.instance.addPersistentFrameCallback((_) {
// 每一帧都会调用
print('Persistent frame callback');
});
// 调度微任务
SchedulerBinding.instance.scheduleTask<void>(() {
print('Scheduled task executed');
}, Priority.animation);
}
}
2.4 GestureBinding - 手势事件处理
dart
class GestureBindingExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GestureDetector(
onTapDown: (details) {
// 直接使用原始手势信息
print('Tap down position: ${details.globalPosition}');
// 访问手势绑定的底层信息
var pointerEvent = GestureBinding.instance.pointerRouter.registeredRoutes;
print('Registered pointer routes: $pointerEvent');
},
child: Container(
width: 200,
height: 200,
color: Colors.blue,
),
);
}
void demonstrateGestureBinding() {
// 手动添加手势路由
GestureBinding.instance.pointerRouter.addRoute(
1, // 指针ID
(PointerEvent event) {
print('Custom pointer route: $event');
}
);
}
}
2.5 RendererBinding - 渲染管理
dart
class RendererBindingExample {
void demonstrateRendererBinding() {
// 监听视图尺寸变化
RendererBinding.instance.window.onMetricsChanged = () {
print('Screen metrics changed');
print('Physical size: ${RendererBinding.instance.window.physicalSize}');
print('Device pixel ratio: ${RendererBinding.instance.window.devicePixelRatio}');
};
// 手动触发绘制
RendererBinding.instance.renderView.markNeedsPaint();
}
// 自定义绘制
void customPainting(Canvas canvas) {
RendererBinding.instance.renderView.paint(
PaintingContext(canvas, Rect.largest),
Offset.zero
);
}
}
2.6 SemanticsBinding - 无障碍功能
dart
class SemanticsBindingExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Semantics(
label: '无障碍标签',
hint: '这是一个示例组件',
child: ElevatedButton(
onPressed: () {},
child: Text('语义化按钮'),
),
);
}
void demonstrateSemanticsBinding() {
// 监听语义树变化
SemanticsBinding.instance.semanticsEnabled = true;
SemanticsBinding.instance.addSemanticsTreeChangeListener(
(SemanticsUpdate update) {
print('Semantics tree updated');
// 处理语义树变化
}
);
}
}
2.7 PaintingBinding 图像绘制和解码
- 管理图像缓存
dart
class PaintingBindingCacheExample {
void demonstrateImageCache() {
// 获取图像缓存实例
PaintingBinding.instance.imageCache.clear();
// 配置图像缓存
PaintingBinding.instance.imageCache.maximumSize = 100;
PaintingBinding.instance.imageCache.maximumSizeBytes = 10 * 1024 * 1024; // 10MB
// 监听缓存状态
print('当前缓存大小: ${PaintingBinding.instance.imageCache.currentSize}');
print('当前缓存字节数: ${PaintingBinding.instance.imageCache.currentSizeBytes}');
}
// 自定义图像缓存处理
Future<void> customImageCaching() async {
// 加载并缓存图像
final ImageStream imageStream = NetworkImage('https://example.com/image.png')
.resolve(ImageConfiguration.empty);
imageStream.addListener(
ImageStreamListener((ImageInfo imageInfo, bool synchronousCall) {
// 图像加载成功
PaintingBinding.instance.imageCache.putIfAbsent(
'https://example.com/image.png',
() => imageInfo,
);
})
);
}
}
- 处理图像解码
dart
class PaintingBindingDecodingExample {
Future<void> demonstrateImageDecoding() async {
// 使用PaintingBinding解码图像
final Uint8List imageBytes = await _loadImageBytes();
final Codec codec = await PaintingBinding.instance.instantiateImageCodec(
imageBytes,
// 可选参数:目标大小、色彩配置等
targetWidth: 100,
targetHeight: 100,
);
// 获取第一帧
final FrameInfo frameInfo = await codec.getNextFrame();
// 使用解码后的图像
print('图像宽度: ${frameInfo.image.width}');
print('图像高度: ${frameInfo.image.height}');
}
// 模拟加载图像字节
Future<Uint8List> _loadImageBytes() async {
// 实际应用中从网络或本地加载
return Uint8List.fromList([]);
}
}
- 管理绘制资源
dart
class PaintingBindingCustomPaintingExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CustomPaint(
painter: _CustomPainter(),
);
}
void demonstrateCustomPainting() {
// 创建图像
PaintingBinding.instance.createImageFromTexture(
(canvas, image) {
// 在画布上绘制
canvas.drawImage(image, Offset.zero, Paint());
},
width: 100,
height: 100,
);
}
}
class _CustomPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
// 使用PaintingBinding相关功能
final Paint paint = Paint()
..color = Colors.blue
..style = PaintingStyle.fill;
canvas.drawCircle(
Offset(size.width / 2, size.height / 2),
50,
paint
);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}
- 提供图像加载和处理的底层机制
dart
class PaintingBindingImageTransformationExample {
Future<void> demonstrateImageTransformation() async {
// 加载原始图像
final ui.Image originalImage = await _loadImage();
// 创建图像描述
final ImageDescriptor descriptor = ImageDescriptor.raw(
await ui.ImmutableBuffer.fromUint8List(
await originalImage.toByteData(format: ui.ImageByteFormat.png)
as Uint8List
),
width: originalImage.width,
height: originalImage.height,
pixelFormat: ui.PixelFormat.rgba8888,
);
// 图像变换
final ui.Image transformedImage = await PaintingBinding.instance.transformImage(
originalImage,
(Canvas canvas) {
// 在这里进行图像变换
canvas.rotate(3.14159); // 旋转180度
canvas.scale(0.5); // 缩放
}
);
print('转换后图像尺寸: ${transformedImage.width} x ${transformedImage.height}');
}
Future<ui.Image> _loadImage() async {
// 实际应用中加载图像
return Completer<ui.Image>().future;
}
}
setState
dart
// Flutter中setState到渲染的核心流程解析
// 1. 状态管理的基本Widget示例
class StateManagementExample extends StatefulWidget {
@override
_StateManagementExampleState createState() => _StateManagementExampleState();
}
class _StateManagementExampleState extends State<StateManagementExample> {
int _counter = 0;
// 调用setState触发重建
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Text('Counter: $_counter');
}
}
// 2. setState的源码简化伪代码
class State<T extends StatefulWidget> {
// setState的核心实现
void setState(VoidCallback fn) {
// 1. 执行状态更新的闭包
fn();
// 2. 标记Element为dirty
_element.markNeedsBuild();
}
}
// 3. Element的核心结构
abstract class Element extends DiagnosticableTree implements BuildContext {
// 对应的Widget
Widget _widget;
// 父Element
Element _parent;
// 子Elements
List<Element> _children;
// 标记为需要重建
void markNeedsBuild() {
// 将Element加入重建队列
scheduleBuildFor(this);
}
// 实际rebuilding的方法
void rebuild() {
if (!_dirty) return;
// 调用build方法重新构建Widget
Widget built = build();
// 更新渲染对象
_updateChild();
}
}
// 4. RenderObject的基本结构
abstract class RenderObject extends Object implements HitTestable {
// 绘制方法
void paint(PaintingContext context, Offset offset) {
// 实际绘制逻辑
}
// 布局方法
void layout(Constraints constraints) {
// 确定渲染对象的大小和位置
}
// 更新渲染树
void performRebuild() {
// 重新计算布局和绘制
}
}
// 5. 渲染流程的关键步骤
class RenderingProcess {
void _updateRenderTree() {
// 1. setState触发
// 2. Element被标记为dirty
// 3. 触发rebuild
// 4. 重新创建Widget
// 5. 更新Element树
// 6. 更新RenderObject
// 7. 触发重绘
}
}
// 关键流程解释:
// 1. setState调用时,会执行状态更新的闭包
// 2. 将对应的Element标记为dirty
// 3. 触发Element的rebuild方法
// 4. 重新调用build()方法创建新的Widget
// 5. 比较新旧Widget,最小化更新渲染树
// 6. 最终触发绘制管道,更新屏幕显示
drawFrame方法什么时候调用
drawFrame 的调用链路涉及到 Flutter 的渲染管线,让我们从上到下看这个调用链:
1. 最顶层触发:VSync 信号
dart
// Flutter引擎接收到VSync信号后,通过平台通道调用beginFrame
@pragma('vm:entry-point')
void _beginFrame(Duration rawTimeStamp) {
// ...
}
2. 什么时候调用
dart
//首次构建(runApp
void runApp(Widget app) {
WidgetsFlutterBinding.ensureInitialized()
..scheduleAttachRootWidget(app)
..scheduleFrame();
}
void setState(VoidCallback fn) {
// ...
scheduleBuildFor(context); // 标记需要重建
SchedulerBinding.instance.scheduleFrame(); // 请求新的帧
}
//动画运行时
void _scheduleFrame() {
SchedulerBinding.instance.scheduleFrame();
}