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

Flutter中Main.dart使用Provider结合Socket.IO接收数据报错求助

问题原因

你在initState中传入的context是MyApp组件的上下文,此时MultiProvider还未完成构建,这个上下文无法访问到内部的SocketDataProvider;同时你存储的_providerContext不属于MultiProvider的子树,导致调用Provider.of时出错。

解决方案

调整Socket初始化时机,在MultiProvider构建完成后使用其子树的上下文访问Provider,同时优化生命周期管理避免内存泄漏。

修改后的完整代码

import 'package:audioplayers/audioplayers.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import './providers/socket_data_provider.dart';
import 'package:wineasy/screens/dashboard.dart';
import 'package:wineasy/screens/test.dart';
import 'package:socket_io_client/socket_io_client.dart' as IO;

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final player = AudioPlayer();
  late IO.Socket socket;

  @override
  void initState() {
    super.initState();
    // 初始化Socket实例
    socket = IO.io('http://localhost:4848', <String, dynamic>{
      'transports': ['websocket'],
      'autoConnect': false
    });
  }

  void _initializeSocket(BuildContext providerContext) {
    socket.connect();

    socket.onConnect((data) {
      print('connected');

      socket.on('orderToKitchen', (orders) async {
        // 使用Provider子树的上下文获取实例
        Provider.of<SocketDataProvider>(providerContext, listen: false)
            .setSocketData(orders);

        await player.play(AssetSource('music/alertTone1.mp3'));
      });
    });

    socket.onDisconnect((data) => print('disconnected'));
  }

  @override
  void dispose() {
    // 断开Socket连接,释放资源
    socket.disconnect();
    player.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (context) => SocketDataProvider()),
      ],
      child: Builder(
        // 通过Builder获取MultiProvider子树的上下文
        builder: (providerContext) {
          _initializeSocket(providerContext);
          return MaterialApp(
            debugShowCheckedModeBanner: false,
            theme: ThemeData(
              colorScheme: ColorScheme.fromSeed(seedColor: Colors.red),
              useMaterial3: true,
            ),
            home: const Scaffold(
              body: Test(),
            ),
          );
        },
      ),
    );
  }
}

确保SocketDataProvider实现正确

import 'package:flutter/foundation.dart';

class SocketDataProvider extends ChangeNotifier {
  List<dynamic> _orders = [];

  List<dynamic> get orders => _orders;

  // 根据后端返回数据类型调整,若为追加订单可改用addAll
  void setSocketData(dynamic orders) {
    _orders = List.from(orders);
    // 必须调用此方法通知UI更新
    notifyListeners();
  }
}

在其他页面使用数据(示例:Test页面)

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../providers/socket_data_provider.dart';

class Test extends StatelessWidget {
  const Test({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    // 监听Provider数据变化,自动更新UI
    final socketProvider = Provider.of<SocketDataProvider>(context);
    
    return Center(
      child: socketProvider.orders.isEmpty
          ? const Text('暂无订单')
          : ListView.builder(
              itemCount: socketProvider.orders.length,
              itemBuilder: (context, index) {
                final order = socketProvider.orders[index];
                return ListTile(
                  title: Text('订单 ${index + 1}'),
                  subtitle: Text(order.toString()),
                );
              },
            ),
    );
  }
}

内容的提问来源于stack exchange,提问作者Prasenjit Das

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 23:00:32