Flutter资源管理插件disposebag的使用

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

Flutter资源管理插件disposebag的使用

disposebag

DisposeBag 是一个用于帮助取消 StreamSubscriptions 和关闭 Sinks 的 Dart 包。它由 Petrus Nguyễn Thái Học 开发,可以通过 GitHub 仓库获取更多信息和提交问题。

Dart CI Codacy Badge Pub

Medium 文章

使用方法

下面是一个简单的使用示例:

import 'package:disposebag/disposebag.dart';
import 'dart:async';

main() async {
  final controllers = <StreamController>[];
  final subscriptions = <StreamSubscription>[];

  final bag = DisposeBag([...subscriptions, ...controllers]);

  await Stream.value(3).listen(null).disposedBy(bag);
  await StreamController<int>.broadcast().disposedBy(bag);
  await StreamController<int>.broadcast(sync: true).disposedBy(bag);

  await bag.dispose();
  print("Bag disposed. It's all good");
}

API

1. Add, addAll

Future<bool> DisposeBag.add(StreamSubscription);
Future<bool> DisposeBag.add(Sink);
Future<void> DisposeBag.addAll(Iterable<StreamSubscription>);
Future<void> DisposeBag.addAll(Iterable<Sink>);

// extension methods
Future<bool> StreamSubscription.disposedBy(DisposeBag);
Future<bool> Sink.disposedBy(DisposeBag);
Future<void> Iterable<StreamSubscription>.disposedBy(DisposeBag);
Future<void> Iterable<Sink>.disposedBy(DisposeBag);

2. Delete (removes but does not dispose)

bool delete(StreamSubscription);
bool delete(Sink);

3. Remove (removes and disposes)

Future<bool> remove(StreamSubscription);
Future<bool> remove(Sink);

4. Clear, dispose

Future<void> clear();
Future<void> dispose();

示例代码

以下是一个更完整的示例,展示了如何使用 DisposeBag 来管理多个流和订阅:

import 'dart:async';
import 'package:disposebag/disposebag.dart';

List<Object> get _disposables {
  final controllers = <StreamController<Object>>[
    StreamController<int>()
      ..add(1)
      ..add(2),
    StreamController<int>(sync: true)
      ..add(3)
      ..add(4),
    StreamController<int>.broadcast()
      ..add(5)
      ..add(6),
    StreamController<String>.broadcast(sync: true)
      ..add('7')
      ..add('8'),
  ];
  final subscriptions = <StreamSubscription>[
    Stream.periodic(const Duration(milliseconds: 100), (i) => i)
        .listen((data) => print('[1] $data')),
    Stream.periodic(const Duration(milliseconds: 10), (i) => i)
        .listen((data) => print('[2] $data')),
    for (int i = 0; i < controllers.length; i++)
      controllers[i].stream.listen((data) => print('[${i + 3}] $data')),
  ];
  return [...controllers, ...subscriptions];
}

void main() async {
  DisposeBagConfigs.logger = disposeBagDefaultLogger;
  final bag = DisposeBag(_disposables);

  // add & addAll
  await bag.add(Stream.value(1).listen(null));
  await bag.addAll([
    Stream.value(2).listen(null),
    Stream<void>.periodic(const Duration(seconds: 1)).listen(null),
  ]);

  // disposedBy
  await Stream.value(3).listen(null).disposedBy(bag);
  await StreamController<int>.broadcast().disposedBy(bag);
  await StreamController<int>.broadcast(sync: true).disposedBy(bag);

  // await before clearing
  await Future<void>.delayed(const Duration(seconds: 1));
  await bag.clear();
  await bag.clear();
  await bag.clear();

  // adding after clearing
  await Future<void>.delayed(const Duration(seconds: 1));
  await Stream.periodic(const Duration(milliseconds: 100), (i) => i)
      .listen(print)
      .disposedBy(bag);

  // await before disposing
  await Future<void>.delayed(const Duration(seconds: 2));
  await bag.dispose();
  print("Bag disposed: ${bag.isDisposed}. It's all good");
  await Future<void>.delayed(const Duration(seconds: 2));
}

通过 DisposeBag,你可以更方便地管理流和订阅的生命周期,确保在适当的时候释放资源,避免内存泄漏。希望这个插件能帮助你在 Flutter 应用中更好地管理资源!如果有任何问题或建议,欢迎访问 GitHub 仓库 提交 issue。


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

1 回复

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


在Flutter开发中,资源管理是一个重要的方面,尤其是在管理内存和避免内存泄漏时。disposebag 并不是 Flutter 官方提供的一个资源管理插件,但类似的概念可以通过 Flutter 的 State 管理机制、Provider、GetX 等状态管理库来实现资源的自动释放。为了模拟 disposebag 的功能,我们可以利用 Flutter 的 AutomaticKeepAliveClientMixin 或者在自定义控制器中实现 dispose 方法来管理资源。

下面是一个使用 Flutter 和 Provider 状态管理库来模拟资源管理释放的例子。在这个例子中,我们将创建一个简单的计数器应用,并确保在不再需要时释放资源。

1. 创建计数器模型(CounterModel)

首先,我们创建一个简单的计数器模型,这个模型包含增加计数器和释放资源的方法。

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

class CounterModel with ChangeNotifier {
  int _count = 0;

  int get count => _count;

  void increment() {
    _count++;
    notifyListeners();
  }

  @override
  void dispose() {
    // 在这里释放资源,比如取消订阅、关闭文件流等
    print("CounterModel resources are being disposed.");
    super.dispose();
  }
}

2. 创建计数器页面(CounterPage)

接下来,我们创建一个页面来使用这个计数器模型,并处理资源的释放。

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'counter_model.dart';

class CounterPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Counter with Resource Management'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '${context.read<CounterModel>().count}',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          context.read<CounterModel>().increment();
        },
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

3. 在主应用中提供计数器模型(MainApp)

最后,我们在主应用中提供这个计数器模型,并确保在应用关闭时释放资源。由于 Flutter 的 Provider 库会自动管理依赖的生命周期,我们不需要手动调用 dispose,但可以通过监听应用的生命周期来模拟这一过程。

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'counter_model.dart';
import 'counter_page.dart';

void main() {
  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => CounterModel()),
      ],
      child: MyApp(),
    ),
  );
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance!.addObserver(this);
  }

  @override
  void dispose() {
    WidgetsBinding.instance!.removeObserver(this);
    // 手动触发 Provider 的 dispose,模拟应用关闭时的资源释放
    Provider.of<CounterModel>(context, listen: false).dispose();
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (state == AppLifecycleState.detached) {
      // 当应用进入后台或被系统回收时,可以在这里执行一些清理操作
      print("App is going to the background or being terminated.");
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: CounterPage(),
    );
  }
}

总结

虽然 Flutter 没有直接的 disposebag 插件,但通过使用 Provider 或其他状态管理库,结合 Flutter 的生命周期管理,我们可以有效地管理应用的资源。上面的例子展示了如何使用 ProviderChangeNotifier 来创建一个简单的计数器应用,并在应用关闭时释放资源。这种方法可以扩展到更复杂的应用场景中,确保资源的正确管理和释放。

回到顶部