Flutter资源管理插件stream_disposable的使用

发布于 1周前 作者 eggper 来自 Flutter

Flutter资源管理插件stream_disposable的使用

标题

Stream Disposable

内容

  • Package介绍stream_disposable 是一个帮助处理 StreamsSinks 的包。
  • 简单使用示例
    • 创建一个可丢弃的对象:
      var disposable = StreamDisposable();
      
    • 添加 StreamSubscriptionSink 到它:
      var streamToDispose = Stream.fromIterable([1, b, as]);
      disposable.add(streamToDispose.listen(print))
      
    • 在状态类的 dispose 方法中或等效的地方,可以调用:
      disposable.dispose(className: this.runtimeType.toString())
      

可用方法

  • add: 添加一个 Sink 或一个 StreamSubscription 到可丢弃的对象。如果添加了另一种类型的对象或可丢弃的对象已经被丢弃,则会抛出错误。
  • Future<void> didDispose: 当 StreamDisposable 被丢弃时完成的 Future
  • bool isDisposed: 检查可丢弃的对象是否已被丢弃的布尔值。
  • Future<void> dispose: 处理当前的 SinkStreamSubscription 并将它们从这个实例中移除。如果在处理 dispose 行动或可丢弃的对象已经被丢弃时抛出错误。

示例代码

import 'dart:async';

import 'package:flutter/material.dart';

import 'package:stream_disposable/stream_disposable.dart';

void main() =&gt; runApp(MyApp());

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  [@override](/user/override)
  _MyHomePageState createState() =&gt; _MyHomePageState();
}

class _MyHomePageState extends State&lt;MyHomePage&gt; {
  int _counter = 0;

  var disposable = StreamDisposable();

  void _incrementCounter() {
    Navigator.of(context)
        .push(MaterialPageRoute(builder: (context) =&gt; PageB()));
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: &lt;Widget&gt;[
            Container(
              padding: EdgeInsets.symmetric(horizontal: 20),
              child: Text(
                'Click on the button to go to the next page and stop counting:',
                softWrap: true,
                textAlign: TextAlign.center,
              ),
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.displayLarge,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }

  [@override](/user/override)
  void initState() {
    super.initState();
    var controller = StreamController&lt;int&gt;();
    var sink = controller.sink;
    var stream = controller.stream;
    disposable.add(stream.listen((data) {
      setState(() {
        _counter = data;
      });
    }));

    disposable.add(sink);

    Timer.periodic(Duration(milliseconds: 500), (i) {
      try {
        sink.add(i.tick);
      } catch (e) {
        print("Closed sink");
        i.cancel();
      }
    });
  }

  /// When pushing, we will dispose of the stream
  [@override](/user/override)
  void deactivate() {
    super.deactivate();
    disposable.dispose(className: this.runtimeType.toString());
  }
}

class PageB extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Page B"),
      ),
      body: Container(
        color: Colors.amber,
      ),
    );
  }
}

更多关于Flutter资源管理插件stream_disposable的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter资源管理插件stream_disposable的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter开发中,stream_disposable 是一个用于管理 Stream 订阅的实用插件。它可以帮助你自动管理 Stream 的订阅和取消订阅,特别是在处理 Flutter 的响应式编程时非常有用。下面是一个关于如何在 Flutter 项目中使用 stream_disposable 的代码示例。

首先,确保你的 pubspec.yaml 文件中包含了 stream_disposable 依赖:

dependencies:
  flutter:
    sdk: flutter
  stream_disposable: ^x.y.z  # 替换为最新版本号

然后运行 flutter pub get 来获取依赖。

接下来,你可以在你的 Flutter 应用中使用 stream_disposable。以下是一个简单的示例,展示如何管理一个 Stream 的订阅和取消订阅:

import 'package:flutter/material.dart';
import 'package:stream_disposable/stream_disposable.dart';
import 'dart:async';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: StreamDisposableExample(),
    );
  }
}

class StreamDisposableExample extends StatefulWidget {
  @override
  _StreamDisposableExampleState createState() => _StreamDisposableExampleState();
}

class _StreamDisposableExampleState extends State<StreamDisposableExample> {
  late Disposable _disposable;
  late StreamController<int> _controller;

  @override
  void initState() {
    super.initState();

    // 创建一个 StreamController 来模拟数据流
    _controller = StreamController<int>();

    // 使用 stream_disposable 来管理这个 Stream 的订阅
    _disposable = _controller.stream
        .listen(
          (data) {
            // 处理接收到的数据
            print('Received data: $data');
          },
          onError: (error) {
            // 处理错误
            print('Error: $error');
          },
          onDone: () {
            // 处理 Stream 关闭
            print('Stream done');
          },
          cancelOnError: true,
        )
        .addTo(_disposable);  // 将订阅添加到 Disposable 中进行管理
  }

  @override
  void dispose() {
    // 取消订阅并释放资源
    _disposable.dispose();
    _controller.close();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Stream Disposable Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              onPressed: () {
                // 向 Stream 发送数据
                _controller.add(42);
              },
              child: Text('Send Data'),
            ),
            ElevatedButton(
              onPressed: () {
                // 模拟取消订阅(通常会在某些条件下调用,比如页面销毁)
                setState(() {
                  _disposable.dispose();
                  // 注意:在实际应用中,通常不会在按钮点击事件中直接调用 dispose,
                  // 这里只是为了演示如何取消订阅。
                });
              },
              child: Text('Dispose Stream'),
            ),
          ],
        ),
      ),
    );
  }
}

在这个示例中,我们创建了一个 StreamController 来模拟数据流,并使用 stream_disposable 提供的 Disposable 来管理这个 Stream 的订阅。当 dispose 方法被调用时(例如,当 Widget 被销毁时),_disposable.dispose() 会被调用,从而取消订阅并释放资源。

注意:在实际应用中,通常不会在按钮点击事件中直接调用 dispose 方法。这里的按钮点击事件只是为了演示如何取消订阅。在实际场景中,你应该在 dispose 生命周期方法中管理资源的释放。

回到顶部