我正在尝试使用共享首选项来保持用户登录并将其放在启动屏幕中,并且在运行项目时出现了此错误:
[ERROR:flutter / lib / ui / ui_dart_state.cc(157)]未处理的异常:
在dispose()之后调用setState():_SplashScreenState#aa9c8(生命周期
状态:已取消)如果在某个状态上调用setState(),则会发生此错误
不再出现在小部件树中的小部件的对象(例如,
其父窗口小部件不再包含其内部小部件)。这个
当代码从计时器或计算机调用setState()时,会发生错误
动画回调。首选解决方案是取消计时器或
停止收听dispose()回调中的动画。另一个
解决方案是先检查该对象的“ mount”属性
调用setState()以确保对象仍在树中。这个
如果正在调用setState(),则错误可能表明内存泄漏
因为另一个对象保留了对此State对象的引用
从树中删除后。为避免内存泄漏,
考虑在dispose()期间中断对此对象的引用。
数据循环不会停止一次又一次地调用自身。
这是我使用共享首选项的方法:
bool isLoading = true;
init() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
bool isLog = prefs.getBool("islog");
if (isLog == true) {
String email = prefs.getString("email");
String pass = prefs.getString("pass");
setState(() {
signIn(email, pass);
});
} else {
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("Signing in success");
await appProvider.countryList();
setState(() {
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (context) => BottomScreen()));
});
}
userProvider.isLoading = false;
setState(() {
isLoading = false;
});
}
这是我的初始屏幕,其中包含先前的共享首选项代码
@override
Widget build(BuildContext context) {
userProvider = Provider.of<UserProvider>(context, listen: false);
appProvider = Provider.of<AppProvider>(context, listen: false);
init();
return isLoading == true
? Container(
color: Colors.white,
child: Center(
child: CircularProgressIndicator()),
)
: 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,
),
Text(
"Voyager",
textAlign: TextAlign.left,
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 24,
),
),
SizedBox(
height: 8,
),
Text(
"Best Trips deals for your holiday",
textAlign: TextAlign.left,
style: TextStyle(
fontSize: 14,
),
),
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),
),
),
),
),
),
),
Padding(
padding: EdgeInsets.only(
bottom:
24.0 + MediaQuery.of(context).padding.bottom,
top: 16),
child: Container(
child: Material(
color: Colors.transparent,
child: InkWell(
borderRadius:
BorderRadius.all(Radius.circular(24.0)),
highlightColor: Colors.transparent,
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
LoginScreen(context)),
);
},
child: Text(
"Already have account? LogIn",
textAlign: TextAlign.left,
style: TextStyle(
fontSize: 14,
color: Colors.white,
),
),
),
),
),
),
],
),
],
),
),
);
}
那么有人可以帮我解决我的问题吗?
答案 0 :(得分:0)
请在微任务中调用您的init函数。
Future.microtask(() => {init()});
答案 1 :(得分:0)
@Mariam请使用已安装,
if (this.mounted){
setState((){
//Your state change code goes here
});
}
答案 2 :(得分:0)
use mounted before setState
if (isLog) {
String email = prefs.getString("email");
String pass = prefs.getString("pass");
if(mounted)
setState(() {
signIn(email, pass);
});
} else {
if(mounted)
setState(() {
isLoading = false;
});
}