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

Flutter:物理设备SharedPreferences会话保持失效,模拟器正常

问题分析与修复方案

你的代码存在两个核心问题,导致物理设备上重启/切换后台后无法恢复登录状态:

1. 异步初始化未触发UI重建

CheckLoginUusuario是异步方法,initState调用它时不会等待执行完成,首次build时islogin仍为null,直接显示登录页。即使后续从SharedPreferences拿到了true,也没有调用setState通知Flutter更新UI。

2. 服务类中SharedPreferences初始化错误

ValidarLoginServices类里直接在成员变量位置写SharedPreferences prefs = await SharedPreferences.getInstance();是非法的——类成员初始化不能使用await,会导致prefs实例获取失败,登录状态可能无法正确存入。


修正后的代码

登录页面(Frm_Login)

class Frm_Login extends State<frm_Login> {
  bool? islogin;

  Future<void> CheckLoginUusuario() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    bool? loginState = prefs.getBool("CheckEstadoLogin");
    // 获取状态后触发UI重建
    setState(() {
      islogin = loginState;
    });
  }

  @override
  void initState() {
    super.initState();
    CheckLoginUusuario();
  }

  @override
  Widget build(BuildContext context) {
    // 状态未获取完成时显示加载组件
    if (islogin == null) {
      return const Center(child: CircularProgressIndicator());
    }
    return islogin == true 
        ? const MenuPrincipal() 
        : LoginPage(
            child: TextButton(
              onPressed: () {
                if (KeyFormValidaciones.currentState?.validate() ?? false) {
                  validarLoginservices.ValidarLogin(Contrasena.text, Usuario.text, context);
                }
              },
              child: const Text("Login", style: TextStyle(fontSize: 25, color: Colors.white)),
            ),
          );
  }
}

登录验证服务类(ValidarLoginServices)

class ValidarLoginServices {
  Future<void> ValidateLogin(String ContrasenaLogin, String CorreoLogin, BuildContext context) async {
    // 移到方法内部获取SharedPreferences实例
    SharedPreferences prefs = await SharedPreferences.getInstance();
    // 替换为你的账号密码验证逻辑
    if (ContrasenaLogin.isNotEmpty && CorreoLogin.isNotEmpty) {
      await prefs.setBool("CheckEstadoLogin", true);
      Navigator.of(context).pushAndRemoveUntil(
        MaterialPageRoute(builder: (context) => const MenuPrincipal()),
        (route) => false
      );
    }
  }
}

额外优化建议

  • 可以在启动页(SplashScreen)完成登录状态检查,再跳转对应页面,用户体验更流畅。
  • 给SharedPreferences的key定义常量,避免拼写错误:const String loginStateKey = "CheckEstadoLogin";

内容的提问来源于stack exchange,提问作者Anes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 11:17:01