Flutter DataStream 未正确关闭和重新构建。[错误状态:Stream 已被收听。]

Art*_*ing 5 data-stream ios flutter

好的,所以我知道可以使用广播系统制造一个流来多次收听一个流,但这不是我在这里想要做的。

我也在编辑这个,因为我收到的一个答案目前无法解决我的问题,因此我们将不胜感激。

由于某种原因,我拥有的代码实际上并没有完全删除流,如果重新使用,它会尝试重新收听已经被收听和关闭的同一个流,但没有一个有效(显然)。我没有尝试再次收听相同的流,而是尝试创建一个新的流来收听。(删除并清除原始第一个流中的所有信息)。

原帖继续如下:

我正在使用 DataStream 模板将数据传入和/或传出程序的各个部分,我不完全确定如何纠正这个问题。我确定这是一个愚蠢的 newb 错误,但我还没有使用 DataStreams 来理解为什么会发生这种情况。

现在不要误会我的意思,通过我的程序的一个周期运行得非常好,完全没有问题。但是,一旦我通过程序完成了一个循环,如果我尝试第二次执行,我会收到错误消息:

错误状态:流已被收听。

因此,由此我知道我的程序没有创建新流,而是尝试重新使用原始流,而且我不是 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),
        ),
      ), 
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

文件 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();
  }

}
Run Code Online (Sandbox Code Playgroud)

文件 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();
    });
  }


}
Run Code Online (Sandbox Code Playgroud)

有效地,在本例中,您可以单击文本,然后转到第二页,这将在告知时正确更改文本,并在完成后返回原始页面。那将是我的程序的一个“周期”。

你可以看到这个程序会立即处理流。

问题是,如果我再次单击文本,它仍在尝试收听原始流,而不是创建全新的流并重新开始。

为什么?我该如何解决这个问题?

Art*_*ing 0

啊哈!我设法弄清楚了。(谢谢大家的帮助,真的非常感谢)。这实际上是一个非常愚蠢的菜鸟错误,当我后退一步时,我就看到了它。

你会注意到在 main.dart 文件中我有一行

DataStream stream = DataStream();
Run Code Online (Sandbox Code Playgroud)

我将其设置为全局变量。因此程序的任何部分都可以根据需要访问信息。这就是我需要设置它的方式......但我忘记了它可以被实例化。

所以我所做的就是将其更改为:

DataStream stream;
Run Code Online (Sandbox Code Playgroud)

然后在我的 main.dart 文件中,就在推动导航器之前,我添加了以下行

stream = new DataStream();
Navigator.push(context, CupertinoPageRoute(builder: (context) => Page2(stream: stream)));
Run Code Online (Sandbox Code Playgroud)

因此,现在我正在创建流的新实例,在从程序的早期部分正确处理它之后。 拍头。一周前应该就知道了。