Flutter应用Stream监听失效问题:如何修复数据流传递?
问题根源与解决方案
你的代码核心问题是多次创建了DatabaseHandler的独立实例,导致监听流的实例和发送数据的实例完全不是同一个对象,两者的StreamController相互独立,所以监听器收不到任何数据。
具体问题点
- 在
initState里调用DatabaseHandler()创建了一个实例,监听它的流 - 在
Timer回调里又调用DatabaseHandler()创建了另一个全新的实例,调用它的startStream发送数据 - 两个实例的
_testStreamController完全分离,数据根本没发到你监听的那个流上
修复方案:使用单例模式确保全局唯一实例
修改DatabaseHandler为单例,保证整个应用中只会存在一个实例,这样生产者和消费者用的是同一个流:
import 'package:flutter/material.dart'; import 'dart:async'; Future<void> main() async { runApp(const MyApp()); Timer.periodic( const Duration(seconds: 4), (timer) { // 调用全局唯一实例 DatabaseHandler().startStream(); } ); } class MyApp extends StatefulWidget { const MyApp({super.key}); @override State<MyApp> createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { late StreamSubscription<int> _streamSubscription; @override void initState(){ super.initState(); // 监听全局唯一实例的流 _streamSubscription = DatabaseHandler().testStream.listen((int i) { print('Received location marker $i'); }); } @override void dispose() { // 取消订阅避免内存泄漏 _streamSubscription.cancel(); // 关闭流控制器释放资源 DatabaseHandler().closeStream(); super.dispose(); } @override Widget build(BuildContext context) { return const MaterialApp( home: Scaffold( body: Center( child: Text('Hello World!'), ), ), ); } } class DatabaseHandler{ late StreamController<int> _testStreamController; Stream<int> get testStream => _testStreamController.stream; // 单例实现:全局唯一实例 static final DatabaseHandler _instance = DatabaseHandler._internal(); factory DatabaseHandler() => _instance; // 私有构造函数,防止外部创建新实例 DatabaseHandler._internal() { _testStreamController = StreamController<int>(); print('Stream initialized'); } void startStream() async { for (int i = 1; i <= 5; i++) { _testStreamController.add(i); print('Added data: $i to stream'); } } // 流关闭方法,释放资源 void closeStream() { _testStreamController.close(); } }
额外优化点
- 添加
StreamSubscription并在dispose中取消订阅,避免内存泄漏 - 给
DatabaseHandler添加流关闭方法,在应用退出或不再需要时释放资源 - 调整打印日志内容,让调试信息更清晰
内容的提问来源于stack exchange,提问作者RJrules64
相关产品推荐
相关产品推荐

