流订阅在flutter应用中投掷dart中的错误?

时间:2018-03-20 14:58:14

标签: dart flutter

我正在使用我的flutter中的connectivity插件来检查连接状态,但偶尔也会遇到错误PlatForm Exception(No active stream to cancel, null),即使我已经处理了空案例。我已在initState订阅了该流,并取消了dispose

中的订阅

我的代码看起来像这样。

    StreamSubscription streamConnectionStatus;
    ------------
    //remaining code
    ------------
    @override
    void initState() {
    getConnectionStatus();
  }

getConnectionStatus() async {
    streamConnectionStatus = new Connectivity()
        .onConnectivityChanged
        .listen((ConnectivityResult result) {
      // Got a new connectivity status!

      if (result == ConnectivityResult.mobile ||
          result == ConnectivityResult.wifi) {
        setState(() {
          boolHasConnection = true;
        });
      } else {
        setState(() {
          boolHasConnection = false;
        });
      }
    });

@override
  void dispose() {
    try {
      streamConnectionStatus?.cancel();
    } catch (exception, stackTrace) {
      print(exception.toString());
      updateError(exception.toString(), stackTrace);
    } finally {
      super.dispose();
    }
  }

这实际上让我发疯,但我猜我错过了什么,或者我是否需要更改代码。

非常感谢, 鳅

2 个答案:

答案 0 :(得分:2)

我遇到了类似的问题。这就是帮助我的原因。

我已在同一窗口小部件树的不同窗口小部件中订阅了连接插件公开的流。我从子窗口小部件中删除了订阅,仅在父窗口中保留了该订阅,并将连接状态从父窗口传递给了子窗口。

这样做,我的代码变得更加整洁,流订阅仅在一个地方维护/处置。然后我再也没有遇到这个问题。

答案 1 :(得分:0)

我认为您的dispose函数是在getConnectionStatus内定义的。 IDE可能不会抛出错误,因为它仍然是有效的定义。只需将其从内部移除,并确保它位于相应的类中。你的代码就像魅力一样。

示例:

class ConnectivityExample extends StatefulWidget {
  @override
  _ConnectivityExampleState createState() => new _ConnectivityExampleState();
}

class _ConnectivityExampleState extends State<ConnectivityExample> {
  StreamSubscription streamConnectionStatus;

  bool boolHasConnection;

  @override
  void initState() {
    getConnectionStatus();
  }

  Future<Null> getConnectionStatus() async {
    streamConnectionStatus = new Connectivity()
        .onConnectivityChanged
        .listen((ConnectivityResult result) {
      debugPrint(result.toString());

      if (result == ConnectivityResult.mobile ||
          result == ConnectivityResult.wifi) {
        setState(() {
          boolHasConnection = true;
        });
      } else {
        setState(() {
          boolHasConnection = false;
        });
      }
    });
  }

  // dispose function inside class
  @override
  void dispose() {
    try {
      streamConnectionStatus?.cancel();
    } catch (exception, stackTrace) {
      print(exception.toString());
    } finally {
      super.dispose();
    }
  }

  @override
  Widget build(BuildContext context) {
    return new Container(
      color: Colors.white,
      alignment: Alignment.center,
      child: new Text(boolHasConnection.toString()),
    );
  }
}

希望有所帮助!