Flutter- понимание жизненного цикла провайдера, блока и того, когда следует утилизировать поток
Нужно понимать, когда нам нужно Bloc-шаблон и жизненный цикл Bloc (как освобождать объекты, хранящие память)
У меня есть экран, на котором я получаю данные с сервера, и данные будут использоваться только для одного экрана. Я использую шаблон Bloc, чтобы показать данные.
При использовании шаблона Bloc у меня появляется экран, на котором я использую StatelessWidget. Я пытаюсь избавиться от потока на "WillPopScope". После утилизации поток больше не может быть использован. Потому что посещение того же экрана приводит к сбою, так как я обернул свое MaterialApp блоком.
- создал поток
final _leaderBoardList = StreamController<List<dynamic>>.broadcast();
- выбрасывать поток
dispose() {
print('_leaderBoardList disposed');
_leaderBoardList.close();
}
- Упаковка материалов приложения внутри провайдера:
LeaderBoardProvider(
child: MaterialApp(
title: 'Table View Fetch',
theme: ThemeData(
primarySwatch: Colors.teal,
),
home: HomeScreen(),
),
);
- Statelesswidget 'WillPopScope', я прокомментировал удаление кода, так как в настоящее время блок создается один раз, как я понял:
Widget build(BuildContext context) {
print(' ListView fetch Build called');
final bloc = LeaderBoardProvider.of(context);
bloc.fetchLeaderBoards();
return WillPopScope(
onWillPop: () async {
//bloc.dispose();
return true;
},
child: bodyStack(context, bloc),
);
}
Первый вопрос. Предположим, я создал широковещательный поток и удалил удаление кода в "WillPopScope", затем все работает, как и ожидалось, но я думаю, что таким образом мой блок удерживает память на время жизни приложения.
Второй вопрос, как обрабатывать такие случаи, когда данные используются на экране. Рекомендуется ли для этой ситуации шаблон Bloc?
1 ответ
Вы не должны распоряжаться BLoC в пределах WillPopScope
,
Задачей вашего "провайдера" является утилизация вашего BLoC: он должен закрывать потоки, когда виджет провайдера удаляется из дерева.
Это достигается тем, что ваш провайдер является StatefulWidget
(с внутренней частной InheritedWidget
разоблачить БЛОК) и переопределить dispose
метод.
Смотрите Flutter: Как правильно использовать Inherited Widget? для примера (это не относится к BLoC и не имеет dispose
, но идея похожа).