Flutter中Navigator Pop页面后函数仍运行,如何彻底销毁页面与函数?
Flutter页面pop后while循环仍持续执行的解决方法
问题描述
从NextScreen页面通过Navigator.pop返回HomeScreen后,预期页面会被销毁且所有关联函数停止运行,但实际startLoopStatus中的while循环仍在持续执行,导致Config.count不断增加、相关日志持续输出。
问题原因
- 循环的终止条件
status == false && isCurrentStatus未与页面生命周期绑定,页面销毁时没有修改这两个变量,循环会一直满足条件继续执行。 - Dart的异步任务一旦启动,会在事件队列中持续运行,直到循环条件不满足,不会因为页面State被dispose而自动停止。
解决方案
在页面的dispose方法中修改循环控制变量,主动终止while循环:
修改后的完整代码
import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class Config { static int count = 0; } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), useMaterial3: true, ), home: const HomeScreen(), ); } } class NextScreen extends StatefulWidget { const NextScreen({super.key}); @override State<NextScreen> createState() => _NextScreenState(); } class _NextScreenState extends State<NextScreen> { int timerCount = 0; bool status = false; bool isCurrentStatus = true; @override void initState() { super.initState(); getInit(); } void getInit() { try { WidgetsBinding.instance.addPostFrameCallback((_) async { startLoopStatus(); }); } catch (e) { print('[getInit] ERROR:: $e'); } } Future<void> startLoopStatus() async { print('[startLoopStatus] Running startLoopStatus 001.'); print(isCurrentStatus); while (status == false && isCurrentStatus) { if (mounted) { setState(() { timerCount += 1; }); } await Future.delayed(const Duration(seconds: 2), () { debugPrint("delay----------"); Config.count += 1; print(Config.count); }); await loopArrive(); } print('[startLoopStatus] Loop terminated.'); } Future<void> loopArrive() async { print('[loopArrive] Running loopArrive 001.'); print('[loopArrive] timerCount: $timerCount'); try { if (mounted && ModalRoute.of(context)!.isCurrent) { print('[loopArrive] Running loopArrive 002.'); } } catch (e) { print('[loopArrive] ERROR:: $e'); } } @override void dispose() { print('[NextScreen] dispose()'); // 修改控制变量,终止while循环 isCurrentStatus = false; status = true; super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Next'), leading: IconButton( icon: const Icon(Icons.arrow_back), onPressed: () { Navigator.of(context).pop(); }, ), ), body: const SafeArea( child: Center( child: Column( children: [ Text('Please see the terminal output.'), ], ), ), ), ); } } class HomeScreen extends StatefulWidget { const HomeScreen({super.key}); @override State<HomeScreen> createState() => _HomeScreenState(); } class _HomeScreenState extends State<HomeScreen> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Home'), ), body: SafeArea( child: Center( child: Column( children: [ ElevatedButton( onPressed: () { Navigator.push( context, MaterialPageRoute(builder: (_) => const NextScreen()), ); }, child: const Text('Go to next page'), ), ], ), ), ), ); } }
关键修改点
在
dispose方法中终止循环:@override void dispose() { print('[NextScreen] dispose()'); isCurrentStatus = false; status = true; super.dispose(); }这会让while循环的条件
status == false && isCurrentStatus变为false,循环在下一次迭代时自动退出。优化状态更新逻辑:
移除了多余的Future.delayed(Duration.zero),直接在mounted判断内调用setState,简化代码逻辑。添加循环终止日志:
在startLoopStatus的while循环结束后添加日志,方便确认循环已终止。
内容的提问来源于stack exchange,提问作者chris
相关产品推荐
相关产品推荐

