颤抖:共享首选项问题

时间:2020-02-27 05:56:58

标签: flutter dart sharedpreferences

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

这是我得到的错误

[ERROR:flutter / lib / ui / ui_dart_state.cc(157)]未处理的异常: 在dispose()之后调用setState():_SplashScreenState#e691a(lifecycle 状态:已失效,未安装)E / flutter(2799):如果发生此错误 您在State对象上为不再需要的小部件调用setState() 出现在小部件树中(例如,其父小部件不再 在其构建中包含小部件)。代码时可能会发生此错误 从计时器或动画回调调用setState()。 E /颤振( 2799):首选解决方案是取消计时器或停止收听 到dispose()回调中的动画。另一个解决方案是 在调用setState()之前检查此对象的“ mount”属性 确保对象仍在树中。 E / flutter(2799):此 如果正在调用setState(),则错误可能表明内存泄漏 因为另一个对象保留对此State对象的引用 从树上将其移除后。为避免内存泄漏, 考虑在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()));
      });

    }

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

1 个答案:

答案 0 :(得分:0)

您正在使用名为“ setState”的async方法调用signIn()',而无需检查小部件是否处于活动状态。

正确的解决方案

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

快速解决方案

步骤:

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