【发布时间】:2020-05-22 20:21:26
【问题描述】:
好的,所以我知道使用广播系统可以制造一个流来不止一次地收听一个流,但这并不是我在这里想要做的。
我也在编辑此问题,因为我收到的一个答案目前无法解决我的问题,因此我们将不胜感激。
由于某种原因,我的代码实际上并没有完全删除流,如果重新使用,它会尝试重新收听已经收听和关闭的同一个流,其中没有一个工作(显然)。我没有尝试再次收听相同的流,而是尝试创建一个新的流来收听。 (删除并清除原始第一个流中的所有信息)。
原帖继续如下:
我正在使用 DataStream 模板将数据流式传输到和/或从我的程序的各个部分流出,我不完全确定如何纠正这个问题。我确定这是一个愚蠢的新手错误,但我没有使用 DataStreams 来理解为什么会发生这种情况。
现在不要误会我的意思,通过我的程序的一个周期可以正常工作,完全没有问题。但是,一旦我通过程序完成了一个循环,如果我尝试第二次,我会收到错误:
错误状态:Stream 已被监听。
因此,我知道我的程序没有创建新流,而是尝试重新使用原始流,而且我不能 100% 确定如何停止此功能,(或者即使我应该)。 (老实说,我希望完成多个周期的次数几乎为零,但我想在这些错误成为问题之前解决它们。)
编辑:要遵循的最小可重复示例
文件 1 (main.dart)
import 'package:flutter/cupertino.dart';
import 'dart:async';
import './page2.dart';
import './stream.dart';
void main() => runApp(MyApp());
DataStream stream = DataStream();
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return CupertinoApp(
title: 'Splash Test',
theme: CupertinoThemeData(
primaryColor: Color.fromARGB(255, 0, 0, 255),
),
home: MyHomePage(title: 'Splash Test Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool textBool = false;
int counter = 0;
void changeTest(context) async {
int counter = 0;
Timer.periodic(Duration (seconds: 2), (Timer t) {
counter++;
stream.dataSink.add(true);
if (counter >= 3) {
t.cancel();
stream.dispose();
Navigator.pop(context);
}
},);
Navigator.push(context, CupertinoPageRoute(builder: (context) => Page2(stream: stream)));
}
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
child: Center(
child: CupertinoButton(
child: Text('To Splash'),
onPressed: () => changeTest(context),
),
),
);
}
}
文件 2 (stream.dart)
import 'dart:async';
class DataStream {
StreamController _streamController;
StreamSink<bool> get dataSink =>
_streamController.sink;
Stream<bool> get dataStream =>
_streamController.stream;
DataStream() {
_streamController = StreamController<bool>();
}
dispose() {
_streamController?.close();
}
}
文件 3 (page2.dart)
import 'package:flutter/material.dart';
import 'package:flutter/semantics.dart';
import './main.dart';
import './stream.dart';
class Page2 extends StatefulWidget {
DataStream stream;
Page2({this.stream});
@override
State<StatefulWidget> createState() => new PageState();
}
class PageState extends State<Page2> {
bool textChanger = false;
bool firstText = true;
Text myText() {
if (textChanger) {
Text text1 = new Text('Text One',
style: TextStyle(color: Color.fromARGB(255, 0, 0, 0)));
return text1;
} else {
Text text1 = new Text('Text Two',
style: TextStyle(color: Color.fromARGB(255, 0, 0, 0)));
return text1;
}
}
void changeText() {
if (!firstText) {
if (textChanger) {
print('Change One');
setState(() {
textChanger = false;
});
} else {
print('Change Two');
setState(() {
textChanger = true;
});
}
} else {
firstText = false;
}
}
@override
Widget build(BuildContext context) {
return new Scaffold(
body: new Container(
child: Center(
child: myText()
)
),);
}
@override
void initState() {
super.initState();
widget.stream.dataStream.listen((onData) {
changeText();
});
}
}
实际上,在本例中,您可以单击文本,然后转到第二页,这将在被告知时正确更改文本,并在完成后返回原始页面。那将是我程序的一个“循环”。
你可以看到这个程序会立即处理流。
问题是,如果我再次点击该文本,它仍在尝试收听原始流,而不是创建一个全新的流并重新开始。
为什么?我该如何解决这个问题?
【问题讨论】:
-
第二个代码块中
stream的作用域是什么?从您拥有的 sn-p 来看,它似乎永远不会被重新实例化? -
“我的程序周期”是什么意思?这可能与导航以及在下一个“周期”中如何推送/弹出 SplashPage 有关。您可以尝试向 SplashPage 添加密钥。
-
@emerssso 我觉得这可能是我遇到的问题之一,但我不确定如何解决它。我的意图是让流实例化,并在需要时收听,并在完成分配的任务后删除。如果需要,可以创建一个全新的。我不认为我正在这样做,但我不一定知道该怎么做。
-
@kuhnroyal “这个程序的循环”我的意思是这个程序被设计成做一件事,用户会通过一系列的提示来完成这个过程。一旦它完成了一次过程,我需要程序完全忘记最初发生的一切,重新开始。如果它试图重新使用原始信息,则会导致问题。
-
如果流只在 SplashPage 中需要,那么就在那里实例化它,否则你肯定有多个订阅者。
标签: ios flutter data-stream