You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中CellPainter绘制图片遇Native Peer回收错误求助

解决CustomPainter绘制图片时的Native Peer回收问题

这个报错的核心原因是图片/矢量图对象被提前垃圾回收,导致Dart对象无法访问已释放的原生资源。以下是针对性的解决方法:

针对PNG图片的处理

  • 提前在State类中持有图片对象,绝对不要在paint方法内临时加载:
    late final Image _pngImage;
    
    @override
    void initState() {
      super.initState();
      _loadPngImage();
    }
    
    void _loadPngImage() async {
      final imageProvider = AssetImage('assets/your_image.png');
      final config = createLocalImageConfiguration(context);
      final imageStream = imageProvider.resolve(config);
      _pngImage = await imageStream.first;
      setState(() {});
    }
    
    @override
    void dispose() {
      _pngImage.dispose(); // 用完记得释放资源
      super.dispose();
    }
    
  • 将加载完成的_pngImage传入CellPainter,在paint方法中绘制:
    canvas.drawImage(_pngImage, Offset(20, 20), Paint());
    

针对SVG图片的处理(以flutter_svg库为例)

  • 提前将SVG解析为Picture对象并持有,避免在绘制时临时解析:
    late final Picture _svgPicture;
    
    @override
    void initState() {
      super.initState();
      _loadSvg();
    }
    
    void _loadSvg() async {
      final svgContent = await rootBundle.loadString('assets/your_icon.svg');
      final drawable = await svg.fromSvgString(svgContent, '');
      _svgPicture = drawable.toPicture(size: Size(50, 50));
      setState(() {});
    }
    
    @override
    void dispose() {
      _svgPicture.dispose();
      super.dispose();
    }
    
  • 在paint方法中绘制:
    canvas.drawPicture(_svgPicture);
    

关键注意事项

  • 禁止在CustomPainter的paint方法内加载/解析图片,该方法会被频繁调用,临时对象极易被GC回收。
  • 确保图片/Picture对象的生命周期与组件绑定,在组件销毁时主动调用dispose释放原生资源。
  • 绘制前判断对象有效性,避免在未加载完成时触发绘制:
    if (_pngImage.isValid) {
      canvas.drawImage(_pngImage, Offset.zero, Paint());
    }
    

内容的提问来源于stack exchange,提问作者Piotr Wosinek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 18:12:05