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

使用share_plus时,如何等待数据加载完成后触发文件分享?

问题分析与解决方案

你的核心问题是分享操作被过早触发(甚至在文件未加载完成时就执行),而且原代码中直接使用snapshot.data!会在数据未就绪时抛出空指针异常。下面是具体的修正思路和代码实现:

原代码的核心问题

  1. 每次FutureBuilder的builder回调触发时(包括初始状态、加载中),都会执行Share.shareXFiles,导致重复分享甚至崩溃。
  2. 没有判断snapshot.hasData就直接取data,空指针风险极高。

方案一:先加载再分享(简洁版)

先弹出加载模态框,等待文件加载完成后关闭模态框再执行分享,逻辑清晰且避免重复触发:

Future<void> share(BuildContext context) async {
  // 先弹出加载模态框
  showModalBottomSheet(
    context: context,
    builder: (context) {
      return SizedBox(
        height: 200,
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: const [
              Text("Preparing sharing…"),
              SizedBox(height: 16),
              CircularProgressIndicator(),
            ],
          ),
        ),
      );
    },
  );

  try {
    // 等待视频文件加载完成
    final fileUrl = await Video.videoUrl(videoUrl!);
    final file = XFile(fileUrl);
    
    // 关闭加载模态框
    Navigator.of(context).pop();
    
    // 仅在文件就绪后执行分享
    await Share.shareXFiles(
      [file],
      text: "Don't miss this out! Only on Shokaze",
    );
  } catch (e) {
    // 加载/分享失败时关闭模态框,可添加错误提示
    Navigator.of(context).pop();
    // ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("分享失败:$e")));
  }
}

方案二:在模态框内切换状态(带分享中提示)

如果需要在模态框内显示"分享中"状态,可以用StatefulBuilder维护状态,确保分享仅执行一次:

Future<void> share(BuildContext context) async {
  showModalBottomSheet(
    context: context,
    builder: (context) {
      return StatefulBuilder(
        builder: (context, setState) {
          bool isPreparing = true;
          
          // 延迟执行异步逻辑,避免阻塞UI构建
          WidgetsBinding.instance.addPostFrameCallback((_) async {
            try {
              // 加载文件
              final fileUrl = await Video.videoUrl(videoUrl!);
              final file = XFile(fileUrl);
              
              // 更新状态为"分享中"
              setState(() {
                isPreparing = false;
              });
              
              // 执行分享
              await Share.shareXFiles(
                [file],
                text: "Don't miss this out! Only on Shokaze",
              );
              
              // 分享完成后关闭模态框
              Navigator.of(context).pop();
            } catch (e) {
              Navigator.of(context).pop();
              // 错误处理
            }
          });
          
          return SizedBox(
            height: 200,
            child: Center(
              child: isPreparing
                  ? Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: const [
                        Text("Preparing sharing…"),
                        SizedBox(height: 16),
                        CircularProgressIndicator(),
                      ],
                    )
                  : const Text("Sharing…"),
            ),
          );
        },
      );
    },
  );
}

关键优化点

  • 确保分享仅在数据就绪后执行:通过await或Future.then等待文件加载完成,再触发分享操作。
  • 避免重复触发:不再在FutureBuilder的builder中直接调用分享,而是将分享逻辑放在异步回调内。
  • 异常处理:添加try-catch捕获加载或分享过程中的错误,避免程序崩溃。

内容的提问来源于stack exchange,提问作者Stéphane de Luca

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 17:06:49