Skip to content

Instantly share code, notes, and snippets.

@Kurogoma4D
Last active January 12, 2024 08:22
Show Gist options
  • Save Kurogoma4D/9e73da0988ab35581723c87a6c2c9cd3 to your computer and use it in GitHub Desktop.
Save Kurogoma4D/9e73da0988ab35581723c87a6c2c9cd3 to your computer and use it in GitHub Desktop.
Using `StreamProvider.future` may cause memory leaks.
// flutter_riverpod: 2.4.9
import 'dart:async';
import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
final random = math.Random();
final baseStreamController = StreamController<int>.broadcast();
final baseStream = StreamProvider.autoDispose(
(ref) => baseStreamController.stream.map((event) => event),
);
final countFuture = FutureProvider.autoDispose((ref) {
return ref.watch(baseStream.future);
});
void main() {
runApp(const ProviderScope(child: MainApp()));
}
class MainApp extends StatelessWidget {
const MainApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Randomize'),
),
body: const Center(
child: _CurrentValue(),
),
floatingActionButton: const _Button(),
),
);
}
}
class _CurrentValue extends ConsumerWidget {
const _CurrentValue();
@override
Widget build(BuildContext context, WidgetRef ref) {
final current = ref.watch(countFuture).valueOrNull;
return Text('Current: $current');
}
}
class _Button extends StatelessWidget {
const _Button();
@override
Widget build(BuildContext context) {
return FloatingActionButton(
onPressed: () => baseStreamController.add(random.nextInt(100)),
child: const Icon(Icons.repeat),
);
}
}
// Below code is not confirmed to memory leak.
import 'dart:async';
import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
final random = math.Random();
final baseStreamController = StreamController<int>.broadcast();
final baseStream = StreamProvider.autoDispose(
(ref) => baseStreamController.stream.map((event) => event),
);
// final countFuture = FutureProvider.autoDispose((ref) {
// return ref.watch(baseStream.future);
// });
void main() {
runApp(const ProviderScope(child: MainApp()));
}
class MainApp extends StatelessWidget {
const MainApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Randomize'),
),
body: const Center(
child: _CurrentValue(),
),
floatingActionButton: const _Button(),
),
);
}
}
class _CurrentValue extends ConsumerWidget {
const _CurrentValue();
@override
Widget build(BuildContext context, WidgetRef ref) {
return FutureBuilder(
future: ref.watch(baseStream.future),
builder: (context, snapshot) => snapshot.hasData
? Text('Current: ${snapshot.data}')
: const Center(
child: CircularProgressIndicator(),
),
);
}
}
class _Button extends StatelessWidget {
const _Button();
@override
Widget build(BuildContext context) {
return FloatingActionButton(
onPressed: () => baseStreamController.add(random.nextInt(100)),
child: const Icon(Icons.repeat),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment