![](/img/trans.png)
[英]popAndPushNamed - Unhandled Exception: This widget has been unmounted, so the State no longer has a context (and should be considered defunct)
[英]Flutter Unhandled Exception: This widget has been unmounted, so the State no longer has a context (and should be considered defunct)
我已经检查了以前的答案,但帮不了我。
我正在检查用户是否有 inte.net,如果没有,我会显示没有 inte.net 的图片。 现在我有一个Retry
按钮,用户可以在其中单击它以检查他是否已返回 inte.net。
现在我在点击Retry
按钮时遇到错误
未处理的异常:此小部件已被卸载,因此 State 不再具有上下文(应被视为已失效)。 E/flutter (25542):考虑在“dispose”期间取消任何活动工作或使用“mounted”getter 来确定 State 是否仍然活动。
我更新的启动画面
class SplashScreen extends StatefulWidget {
const SplashScreen({Key? key}) : super(key: key);
@override
State<SplashScreen> createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> {
Future<bool> isLoggedIn() async {
final prefs = await SharedPreferences.getInstance();
final token = prefs.getString("token");
print("Token obtained: $token");
return token != null;
}
@override
void initState() {
_init();
super.initState();
}
Future<void> _init() async {
bool isConnected = await NetworkHelper.checkInternet();
if (!isConnected) {
if (mounted) {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => CheckConnection(
onRetry: _init,
)),
);
}
} else {
await Future.delayed(const Duration(seconds: 3), () async {
final isTokenValid = await isLoggedIn();
if (isTokenValid) {
if (mounted) {
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => BottomNav()),
);
}
} else {
if (mounted) {
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => Signup()),
);
}
}
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
color: Colors.white,
child: FlutterLogo(size: MediaQuery.of(context).size.height),
),
);
}
}
如果没有 inte.net,这是我的图像。
class CheckConnection extends StatelessWidget {
final VoidCallback onRetry;
const CheckConnection({Key? key, required this.onRetry}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset("assets/image/no_internet.jpg"),
const SizedBox(height: 20),
ElevatedButton(
onPressed: onRetry,
child: const Text("Retry"),
),
],
),
);
}
}
你的代码有问题。 您正在尝试在所谓的asynchronous suspension
之后访问context
,即,您在某些Future
完成其工作后访问context
,而在这种情况下, context
可能处于无效的 state,可能是因为Element
树在期间发生了变化这种“异步暂停”。 我还假设您收到了有关此的警告,但您忽略了它。
这个问题的解决方案是,正如错误提示的那样,在你的Future
完成它的工作之后和你访问context
之前,使用State
class 中可用的 getter mounted
:
await Future.delayed(...);
if(mounted){
// you can use the context
}
else{
// you can't use the context
}
在您的情况下,您需要在 Future 返回后使用它之前通过检查mounted
变量来检查上下文是否仍然有效:
if(mounted) // you should put this check in all places where you use context after an asyncronous suspension
{
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => BottomNav()),
);
}
else{
// the context is not valid
// you should handle this case according to your app needs
}
另请参阅此答案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.