【问题标题】:Flutter StreamSubscription not stopping or pausingFlutter StreamSubscription 没有停止或暂停
【发布时间】:2019-07-20 20:20:36
【问题描述】:

在我的 Flutter 应用程序中,StreamSubscription 没有暂停或取消。当我打电话给cancel() 时,如果它之前开始,它会停止。如果我在启动后调用cancel(),它不会停止。我正在使用 Firestore 快照侦听器。下面是我的代码。 我尝试了不同的方法,但仍然无法正常工作。问题是 Firestore listener 在加载数据后没有停止。

    StreamSubscription<QuerySnapshot> streamSubscription;

    @override
    void initState() {
    super.initState();
    
        print("Creating a streamSubscription...");
        streamSubscription =Firestore.collection("name").document("d1").collection("d1")
            .snapshots().listen((data){
                //It will display items
            }, onDone: () { // Not excecuting
                print("Task Done");
            }, onError: (error) {
                print("Some Error");
        });
         streamSubscription.cancel(); //It will work but cancel stream before loading
    }

    @override
    void dispose() {
     streamSubscription.cancel(); //Not working
    super.dispose();
    }

【问题讨论】:

  • stream.close() 应该是 stream.cancel() 并且 StreamSubscription 应该被称为 streamSubscriptionsubscription 而不是 stream 因为这很令人困惑,因为 Stream 完全是另外一回事.
  • api.dartlang.org/stable/2.2.0/dart-async/… 中没有 close(),所以它不起作用也就不足为奇了。如果您收到错误消息,您应该将该错误消息与您的问题一起发布。
  • 我已经编辑了我的问题。我正在使用“取消()”未关闭。很抱歉发生了错误。
  • @GünterZöchbauer 你知道它为什么没有停止吗?
  • 很难说。可能是因为事件是同步发出的,因此在调用cancel() 之前发出。您的问题对实际发生的事情以及预期的行为不够清楚。如果你能改进它,那么你得到有用答案的可能性就会增加。

标签: firebase firebase-realtime-database dart flutter google-cloud-firestore


【解决方案1】:

当您推送新页面时,仍会呈现前一页面,因此不会调用 dispose()

有时也可能发生小部件不再呈现但尚未调用 dispose 的情况,这可能会导致奇怪的错误消息。因此,如果您使用dispose,添加这样的检查可能也是一个好主意。

改变

//It will display items

if(myIsCurrentRoute && mounted) {
  //It will display items
}

【讨论】:

    【解决方案2】:

    您没有将订阅分配给正确的变量。

    StreamSubscription<QuerySnapshot> subscription;
    
    @override
    void initState() {
    super.initState();
    
        print("Creating a streamSubscription...");
        subscription=Firestore.collection("name").document("d1").collection("d1")
            .snapshots().listen((data){
                //It will display items
            }, onDone: () { // Not excecuting
                print("Task Done");
            }, onError: (error) {
                print("Some Error");
        });
    
    
         subscription.cancel(); //It will work but cancel stream before loading
    
    
    
    }
    
    @override
    void dispose() {
     subscription.cancel(); //Not working
    super.dispose();
    }
    

    【讨论】:

    • 这是我问题中的错误。我改变我的问题。我分配了。在正确的变量中更正订阅。请再次检查问题并检查您的答案。
    • @Joe 您是否尝试过是否调用了 dispose 函数?尝试在 dispose 函数中打印一些东西,看看它是否被调用。
    • 我已经在dispose() 中尝试过,我的 dispose() 正在工作,但没有取消收听。在调用新屏幕之前我也打电话了。 Navigator.push(context,MaterialPageRoute(builder: (context) =&gt; SecondScreen()));
    • 有人能告诉我为什么 onDone 没有在这里执行吗?
    【解决方案3】:

    我遇到了同样的问题,事实证明,流似乎在取消之前一直在监听事件一段时间,但是如果你调试你会看到在调用 dispose 之后它会在某个时候停止监听。 因此,Gunter's 解决方案可以正常工作,因为如果 mount 为 false,您可以阻止回调函数被调用,这意味着您的页面不再存在。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-06
      • 2010-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多