Flutter登录后复用已销毁State实例导致setState报错问题咨询
Flutter登录系统路由跳转后旧State实例残留引发setState报错
我用Flutter的命名路由和Navigator实现了简易登录系统:
- 登录成功时,通过
Navigator.popAndPushNamed(context, '/first')弹出登录路由并跳转首页; - 登录后应用内路由正常入栈出栈,导航流畅;
- 登出时,通过
Navigator.pushNamedAndRemoveUntil(context, '/', (route) => false)清空路由栈返回登录页。
上述流程整体正常,但用户再次登录时,首页(StatefulWidget)会关联已销毁的旧State实例,导致State的mounted属性为false,无法正确初始化属性,进而触发setState() calls after dispose()错误。
我附上了登录系统的示例代码,但该示例无法复现问题,推测原因可能是State销毁时存在未捕获异常。当前使用Flutter 3.7.12(Dart 2.19.6),暂不升级到Dart 3以避免空安全适配重构,错误为偶现,主要出现在Android端。
示例代码:
import 'dart:async'; import 'package:flutter/material.dart'; void main() { runApp( MaterialApp( title: 'Named Routes Demo', initialRoute: '/', routes: { '/': (context) => const LoginScreen(), '/first': (context) => FirstScreen(), '/second': (context) => const SecondScreen(), }, ), ); } class LoginScreen extends StatelessWidget { const LoginScreen({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Loggin screen'), ), body: Center( child: ElevatedButton( onPressed: () => Navigator.popAndPushNamed(context, '/first'), child: const Text('Launch app'), ), ), ); } } class FirstScreen extends StatefulWidget { const FirstScreen({super.key}); FirstState createState() => FirstState(); } class FirstState extends State<FirstScreen> { int cont; Timer? t; final String a; FirstState() : cont = 0, a='a' { debugPrint("Creando estado de First screen"); } @override void initState() { super.initState(); debugPrint("Inicializando estado de First Screen"); cont = 10; t = Timer.periodic(Duration(seconds: 1), (timer) => setState(() => cont++)); } @override void dispose() { debugPrint("Eliminando estado de First Screen"); cont = 0; t?.cancel(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('First Screen'), ), body: Center(child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text("Contador: $cont"), SizedBox(height: 50,), ElevatedButton( onPressed: () { Navigator.pushNamed(context, '/second'); }, child: const Text('Go to second screen'), ), ] ) ), ); } } class SecondScreen extends StatelessWidget { const SecondScreen({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Second Screen'), ), body: Center(child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ ElevatedButton( onPressed: () { Navigator.pop(context); }, child: const Text('Go back'), ), ElevatedButton( onPressed: () { Navigator.pushNamedAndRemoveUntil(context, '/', (route) => false); }, child: const Text('Logout'), ) ] ) ) ); } }
内容的提问来源于stack exchange,提问作者MauroDiamantino
相关产品推荐
相关产品推荐

