You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 04:32:35