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();
}
相关推荐
江上清风山间明月15 小时前
Flutter开发的应用页面非常多时如何高效管理路由
android·flutter·路由·页面管理·routes·ongenerateroute
Zsnoin能1 天前
flutter国际化、主题配置、视频播放器UI、扫码功能、水波纹问题
flutter
早起的年轻人1 天前
Flutter CupertinoNavigationBar iOS 风格导航栏的组件
flutter·ios
HappyAcmen1 天前
关于Flutter前端面试题及其答案解析
前端·flutter
coooliang2 天前
Flutter 中的单例模式
javascript·flutter·单例模式
coooliang2 天前
Flutter项目中设置安卓启动页
android·flutter
JIngles1232 天前
flutter将utf-8编码的字节序列转换为中英文字符串
java·javascript·flutter
B.-2 天前
在 Flutter 中实现文件读写
开发语言·学习·flutter·android studio·xcode
freflying11192 天前
使用jenkins构建Android+Flutter项目依赖自动升级带来兼容性问题及Jenkins构建速度慢问题解决
android·flutter·jenkins
机器瓦力2 天前
Flutter应用开发:对象存储管理图片
flutter