Flutter资源清理插件disposed的使用
Flutter资源清理插件disposed的使用
Disposed
库提供了自动对象清理的包装器,利用了 Finalizer
。
注意事项
DisposableContainer
中的内部 Disposable
对象 必须 不要强引用其父容器,否则将导致内存泄漏,并且对象不仅永远不会被释放,还会一直保留在内存中直到程序运行结束。
功能特点
- 使用此包可以创建对象析构函数。
使用方法
以下是一个示例:
// 包含可处置对象,同时也是可处置自身。
class NotificationsProvider extends DisposableContainer implements Disposable {
final _notificationsController = DisposableStreamController(
StreamController<String>.broadcast(),
);
Stream<String> get notifications => _notificationsController.controller.stream;
void notify(String message) {
_notificationsController.controller.add(message);
}
[@override](/user/override)
late final List<Disposable> disposables = [ _notificationsController, ];
[@override](/user/override)
void dispose() {
// 注意:这将在 [disposables] 被处置之前调用。
print('NotificationsProvider is disposed.');
}
}
// 主容器
class NotificationsCenter extends DisposableContainer {
NotificationsCenter(this.provider);
final NotificationsProvider provider;
void notify(String message) {
provider.notify(message);
}
[@override](/user/override)
late final List<Disposable> disposables = [ provider, ];
}
当示例中的 NotificationsCenter
实例变得不可访问时,内部的 Finalizer
将按以下顺序释放对象:
NotificationsProvider
- 内部可处置对象,也是包装器。DisposableStreamController
- 内部可处置对象。
注意,NotificationsCenter
本身只是一个包装器(主包装器),它不会被处置,而是由语言的垃圾回收器进行垃圾收集。
这种顺序是因为父对象引用了子对象,因此垃圾回收器会先销毁父对象,然后子对象失去引用,也会被销毁。
完整示例代码
/// 在此示例中,我们将创建一个包含通知提供者的通知中心。
///
/// 这将说明如何创建自动关闭的 [Stream]。
library disposed_example;
import 'dart:async';
import 'package:disposed/disposed.dart';
class NotificationsProvider extends DisposableContainer implements Disposable {
final _notificationsController = DisposableStreamController(
StreamController<String>.broadcast(),
);
Stream<String> get notifications => _notificationsController.controller.stream;
void notify(String message) {
_notificationsController.controller.add(message);
}
[@override](/user/override)
late final List<Disposable> disposables = [ _notificationsController, ];
[@override](/user/override)
void dispose() {
// 注意:这将在 [disposables] 被处置之前调用。
print('NotificationsProvider is disposed.');
}
}
class NotificationsCenter extends DisposableContainer {
NotificationsCenter(this.provider);
final NotificationsProvider provider;
void notify(String message) {
provider.notify(message);
}
[@override](/user/override)
late final List<Disposable> disposables = [ provider, ];
}
Future<void> main(List<String> args) async {
// 创建对象。
NotificationsProvider? provider = NotificationsProvider();
NotificationsCenter? center = NotificationsCenter(provider);
// 通过弱引用跟踪GC状态。
final _provider = WeakReference(provider);
final _center = WeakReference(center);
// 监听一些通知。
center.provider.notifications.listen(
(event) => print('New notification: $event'),
onDone: () => print('Notifications done.'),
);
// 执行一些操作。
center.notify('Test!');
await Future<void>.delayed(const Duration(milliseconds: 250));
center.notify('Test 2!');
// 使对象不可访问。
provider = null;
center = null;
// 等待GC。
while (_provider.target != null || _center.target != null) {
await Future<void>.delayed(const Duration(milliseconds: 1));
// 喂养内存以强制GC。
// ignore: unused_local_variable
final bigChunkOfData = '0' * 1024 * 1024 * 5; // 大约5MB的数据。
}
print('Disposables are disposed, objects garbage collected, streams closed.');
}
更多关于Flutter资源清理插件disposed的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter资源清理插件disposed的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter应用中使用disposed
插件进行资源清理的示例。disposed
插件(假设这是一个虚构的插件名称,因为Flutter官方并没有一个名为disposed
的插件,但类似功能可以通过自定义逻辑实现)通常用于在Widget被销毁时清理资源,比如取消网络请求、停止动画、释放内存等。
在Flutter中,我们可以通过Disposable
接口或者类似机制来实现资源清理。虽然没有一个现成的disposed
插件,但你可以通过实现Disposable
接口和重写dispose
方法来达到相同的效果。
以下是一个示例代码,展示如何在Flutter中自定义资源清理逻辑:
- 创建一个可释放资源的类:
class CustomResource {
// 模拟一个需要清理的资源,比如一个计时器
Timer? _timer;
CustomResource(Duration interval, VoidCallback callback) {
_timer = Timer.periodic(interval, callback);
}
// 清理资源的方法
void dispose() {
_timer?.cancel();
_timer = null;
print("CustomResource disposed");
}
}
- 创建一个Widget并使用资源清理逻辑:
import 'package:flutter/material.dart';
class ResourceWidget extends StatefulWidget {
@override
_ResourceWidgetState createState() => _ResourceWidgetState();
}
class _ResourceWidgetState extends State<ResourceWidget> with WidgetsBindingObserver {
CustomResource? _resource;
@override
void initState() {
super.initState();
WidgetsBinding.instance?.addObserver(this);
// 初始化资源
_resource = CustomResource(Duration(seconds: 5), () {
print("Timer ticked");
});
}
@override
void dispose() {
// 清理资源
_resource?.dispose();
_resource = null;
WidgetsBinding.instance?.removeObserver(this);
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Resource Cleanup Example'),
),
body: Center(
child: Text('This widget will clean up resources when disposed.'),
),
);
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
// 这个方法通常用于处理应用生命周期的变化,但在这个例子中我们不需要它
super.didChangeAppLifecycleState(state);
}
}
void main() {
runApp(MaterialApp(
home: ResourceWidget(),
));
}
在这个示例中,我们创建了一个CustomResource
类,它包含一个Timer
,并在dispose
方法中取消该计时器。然后,我们在ResourceWidget
中创建并管理这个资源。在dispose
方法中,我们确保在Widget被销毁时调用_resource?.dispose()
来清理资源。
请注意,虽然这个示例没有直接使用一个名为disposed
的插件,但它展示了如何在Flutter中实现资源清理的逻辑。如果你确实有一个特定的disposed
插件,并且需要更详细的用法,请参考该插件的官方文档或示例代码。