flutter Owner和Binding学习

文章目录

        • [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 图像绘制和解码
  1. 管理图像缓存
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,
        );
      })
    );
  }
}
  1. 处理图像解码
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([]);
  }
}
  1. 管理绘制资源
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;
}
  1. 提供图像加载和处理的底层机制
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();
}
相关推荐
Wuxiaoming1358 小时前
关于flutter与django建立mqtt的研究
flutter
Cao_Shixin攻城狮12 小时前
[Flutter]Json序列化json_serializable使用属性全介绍
flutter·json·serializable
五味香1 天前
Java学习,反射
android·java·开发语言·python·学习·flutter·kotlin
收银系统源码那点事1 天前
零售餐饮收银台源码
flutter·uni-app·零售·收银系统源码·收银系统·连锁店收银系统
唯鹿1 天前
Flutter如何适配RTL
android·flutter
Mis_wenwen1 天前
flutter 解决webview加载重定向h5页面 返回重复加载问题
flutter·h5·webview·重定向
兰琛1 天前
Flutter 1.1:下载Flutter环境
android·flutter
sunly_1 天前
Flutter:购物车总结(单选,全选,定义数量,是否选中为obs响应式)
flutter
吴胜ws1 天前
Flutter中的Future和Stream
flutter
sunly_2 天前
Flutter:常见的页面布局:上边内容可滚动,底部固定一个按钮
android·javascript·flutter