颤动:共享偏好问题

flutter : shared preference issue

我正在尝试向我的应用程序添加一个共享首选项以保存用户的数据以供下次登录,但是我收到一个错误并且我有一个加载数据的无限循环并且我的应用程序在这个循环之后崩溃了。

这是我得到的错误

[ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: setState() called after dispose(): _SplashScreenState#e691a(lifecycle state: defunct, not mounted) E/flutter ( 2799): This error happens if you call setState() on a State object for a widget that no longer appears in the widget tree (e.g., whose parent widget no longer includes the widget in its build). This error can occur when code calls setState() from a timer or an animation callback. E/flutter ( 2799): The preferred solution is to cancel the timer or stop listening to the animation in the dispose() callback. Another solution is to check the "mounted" property of this object before calling setState() to ensure the object is still in the tree. E/flutter ( 2799): This error might indicate a memory leak if setState() is being called because another object is retaining a reference to this State object after it has been removed from the tree. To avoid memory leaks, consider breaking the reference to this object during dispose().

这是在我的启动画面中获得偏好的方法

SharedPreferences prefs = await SharedPreferences.getInstance();
    bool isLog = prefs.getBool("islog");
    print(this.mounted);
    if(this.mounted){
    if (isLog == true) {
      setState(() {
      String email = prefs.getString("email");
      String pass = prefs.getString("pass");
        signIn(email, pass);

         });
     } 
     }else {
      if(!mounted)
      setState(() {
        isLoading = false;
      });
    }
  }

  signIn(String email, String pass) async {
    var res = await userProvider.login(email, pass);

    var user = userProvider.user.tourist;
    if (res is FailedRequest) {
      Dialogs.showErrorDialog(context, message: res.message, code: res.code);

    } else if (user == true) {
      print("Shared ***********************************************");
      await appProvider.countryList();
      await appProvider.activityList();
      await appProvider.tourGuideList();

     setState(() {
        Navigator.pushReplacement(
            context, MaterialPageRoute(builder: (context) => BottomTourist()));
      });
    } 

这是我的闪屏小部件

 @override
  Widget build(BuildContext context) {
    userProvider = Provider.of<UserProvider>(context, listen: false);
    appProvider = Provider.of<AppProvider>(context, listen: false);
    init();
    return Container(
        child: Scaffold(
        body: Stack(
          children: <Widget>[
            Container(
              foregroundDecoration: !AppTheme.isLightTheme
                  ? BoxDecoration(
                      color:
                          AppTheme.getTheme().backgroundColor.withOpacity(0.4))
                  : null,
              width: MediaQuery.of(context).size.width,
              height: MediaQuery.of(context).size.height,
              child: Image.asset('assets/images/introduction.jpg',
                  fit: BoxFit.cover),
            ),
            Column(
              children: <Widget>[
                Expanded(
                  flex: 1,
                  child: SizedBox(),
                ),
                Center(
                  child: Container(
                    width: 60,
                    height: 60,
                    decoration: BoxDecoration(
                      borderRadius: BorderRadius.all(
                        Radius.circular(8.0),
                      ),
                      boxShadow: <BoxShadow>[
                        BoxShadow(
                            color: AppTheme.getTheme().dividerColor,
                            offset: Offset(1.1, 1.1),
                            blurRadius: 10.0),
                      ],
                    ),
                    child: ClipRRect(
                      borderRadius: BorderRadius.all(
                        Radius.circular(8.0),
                      ),
                      child: Image.asset('assets/images/appIcon.png'),
                    ),
                  ),
                ),
                SizedBox(
                  height: 16,
                ),
                Expanded(
                  flex: 4,
                  child: SizedBox(),
                ),
                Padding(
                  padding: const EdgeInsets.only(
                      left: 48, right: 48, bottom: 8, top: 8),
                  child: Container(
                    height: 48,
                    decoration: BoxDecoration(
                      color: AppTheme.getTheme().primaryColor,
                      borderRadius: BorderRadius.all(Radius.circular(24.0)),
                      boxShadow: <BoxShadow>[
                        BoxShadow(
                          color: AppTheme.getTheme().dividerColor,
                          blurRadius: 8,
                          offset: Offset(4, 4),
                        ),
                      ],
                    ),
                    child: Material(
                      color: Colors.transparent,
                      child: InkWell(
                        borderRadius: BorderRadius.all(Radius.circular(24.0)),
                        highlightColor: Colors.transparent,
                        onTap: () {
                          Navigator.push(
                            context,
                            MaterialPageRoute(
                                builder: (context) => IntroductionScreen()),
                          );
                        },
                        child: Center(
                          child: Text(
                            "Get started",
                            style: TextStyle(
                                fontWeight: FontWeight.w500,
                                fontSize: 16,
                                color: Colors.white),
                          ),
                        ),
                      ),
                    ),
                  ),
                ),

              ],
            ),
          ],
        ),
      ),
    );
  }
}

这是我的登录方法,用于为用户设置首选项

signIn() async {
    var res = await userProvider.login(
        _userNameController.text, _passwordController.text);
    var user = userProvider.user.tourist;
    SharedPreferences prefs = await SharedPreferences.getInstance();

    if (res is FailedRequest) {
      Dialogs.showErrorDialog(context, message: res.message, code: res.code);

    } else if (user == true) {
      print("Signing in success");
      await appProvider.countryList();
      await appProvider.activityList();
      await appProvider.tourGuideList();

      setState(() {
        prefs.setBool("islog", true);
        prefs.setString('pass', userProvider.user.password);
        prefs.setString('email', userProvider.user.email);
        Navigator.pushReplacement(widget._context,
            MaterialPageRoute(builder: (context) => BottomTourist()));
      });

    }

所以有人可以帮我解决我的问题吗?

您在名为 'signIn()'async 方法中调用 setState,但未检查小部件是否处于活动状态。

正确的解决方案

您需要为您的应用设置定义明确的状态管理系统。阅读 this 了解更多信息。

快速解决

步骤:

  1. 在您的状态中添加一个 boolean 变量 class 以识别小部件是否处于活动状态。
  2. dispose() 回调中将布尔值设置为 false。
  3. 在异步操作后调用 setState 之前,检查是否 小部件是否存在。