未经手的例外:setState()在distose()时拨打:flutter in flutter
我正在尝试使用setState
更改变量的值,但是它给了我这个错误,
Unhandled Exception: setState() called after dispose(): _SplashState#27d6e(lifecycle state: defunct, not mounted, ticker inactive)
E/flutter (12289): 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 (12289): 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 (12289): 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().
因为上述错误我在屏幕上没有收到通知。
在initstate
函数中,我正在做通知和firebase令牌
并将值存储到sharedPreference
。我希望将特定值存储在变量中,以便我可以在“通知”上点击其他屏幕上访问更新值。
这是我的代码,
class Splash extends StatefulWidget {
const Splash({Key? key}) : super(key: key);
@override
_SplashState createState() => _SplashState();
}
class _SplashState extends State<Splash> with SingleTickerProviderStateMixin {
late AnimationController controller;
late Animation heartbeatAnimation;
@override
void initState() {
super.initState();
controller = AnimationController(
vsync: this, duration: const Duration(milliseconds: 500));
heartbeatAnimation =
Tween<double>(begin: 100.0, end: 250.0).animate(controller);
controller.forward().whenComplete(() {
controller.reverse();
});
Future.delayed(const Duration(seconds: 3), () async {
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
print("onMessage Clicked!");
String getId = message.data["id"];
print("ride id get: ${message.data["id"]}");
if (mounted) {
setState(() {
bookedRideId = int.parse(getId); //this line is not wwrking, error points here
});
}
RemoteNotification? notification = message.notification;
AndroidNotification? android = message.notification?.android;
if (notification != null && android != null) {
flutterLocalNotificationsPlugin.show(
notification.hashCode,
notification.title,
notification.body,
NotificationDetails(
android: AndroidNotificationDetails(
channel.id,
channel.name,
icon: android.smallIcon,
),
));
}
});
getToken();
FirebaseMessaging.onBackgroundMessage(
_firebaseMessagingBackgroundHandler);
// assign channel (required after android 8)
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
// initialize notification for android
var initialzationSettingsAndroid =
AndroidInitializationSettings('@mipmap/ic_launcher');
var initializationSettings =
InitializationSettings(android: initialzationSettingsAndroid);
flutterLocalNotificationsPlugin.initialize(initializationSettings);
final NotificationAppLaunchDetails? notificationAppLaunchDetails =
await flutterLocalNotificationsPlugin
.getNotificationAppLaunchDetails();
payload = notificationAppLaunchDetails!.payload;
if (payload != null) {
routeToGo = '/second';
navigatorKey.currentState?.pushNamed('/second');
}
await flutterLocalNotificationsPlugin.initialize(initializationSettings,
onSelectNotification: selectNotification);
FirebaseMessaging.onMessageOpenedApp
.listen((RemoteMessage message) async {
print(message.notification!.body != null);
if (message.notification!.body != null) {
print("=======================rideid=====================");
print(rideId);
navigatorKey.currentState?.pushNamed('/second');
}
});
SharedPreferences prefs = await SharedPreferences.getInstance();
emailAddress = prefs.getString('email').toString();
token = prefs.getString('token').toString();
emailAddress == "null" && token == "null"
? Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (context) => const PreLogin()),
(route) => false)
: role == "driver"
? Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (context) => DriverHome()),
(route) => false)
: Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (context) => const UserHome()),
(route) => false);
});
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
resizeToAvoidBottomInset: false,
body: Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage(splashBgImage),
fit: BoxFit.fill,
),
),
child: const Logo(),
)),
);
}
}
请帮助我解决此问题。
I'm trying to change the value of a variable using setState
but it gives me this error
Unhandled Exception: setState() called after dispose(): _SplashState#27d6e(lifecycle state: defunct, not mounted, ticker inactive)
E/flutter (12289): 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 (12289): 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 (12289): 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().
Because of the above error i'm not getting notification on my screen.
In initState
function, i'm doing to get the notifications and firebase token
and storing the values to sharedPreference
. I want a specific value to be stored in variable so i can access the updated value on other screen on tap on notification.
here is my code
class Splash extends StatefulWidget {
const Splash({Key? key}) : super(key: key);
@override
_SplashState createState() => _SplashState();
}
class _SplashState extends State<Splash> with SingleTickerProviderStateMixin {
late AnimationController controller;
late Animation heartbeatAnimation;
@override
void initState() {
super.initState();
controller = AnimationController(
vsync: this, duration: const Duration(milliseconds: 500));
heartbeatAnimation =
Tween<double>(begin: 100.0, end: 250.0).animate(controller);
controller.forward().whenComplete(() {
controller.reverse();
});
Future.delayed(const Duration(seconds: 3), () async {
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
print("onMessage Clicked!");
String getId = message.data["id"];
print("ride id get: ${message.data["id"]}");
if (mounted) {
setState(() {
bookedRideId = int.parse(getId); //this line is not wwrking, error points here
});
}
RemoteNotification? notification = message.notification;
AndroidNotification? android = message.notification?.android;
if (notification != null && android != null) {
flutterLocalNotificationsPlugin.show(
notification.hashCode,
notification.title,
notification.body,
NotificationDetails(
android: AndroidNotificationDetails(
channel.id,
channel.name,
icon: android.smallIcon,
),
));
}
});
getToken();
FirebaseMessaging.onBackgroundMessage(
_firebaseMessagingBackgroundHandler);
// assign channel (required after android 8)
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
// initialize notification for android
var initialzationSettingsAndroid =
AndroidInitializationSettings('@mipmap/ic_launcher');
var initializationSettings =
InitializationSettings(android: initialzationSettingsAndroid);
flutterLocalNotificationsPlugin.initialize(initializationSettings);
final NotificationAppLaunchDetails? notificationAppLaunchDetails =
await flutterLocalNotificationsPlugin
.getNotificationAppLaunchDetails();
payload = notificationAppLaunchDetails!.payload;
if (payload != null) {
routeToGo = '/second';
navigatorKey.currentState?.pushNamed('/second');
}
await flutterLocalNotificationsPlugin.initialize(initializationSettings,
onSelectNotification: selectNotification);
FirebaseMessaging.onMessageOpenedApp
.listen((RemoteMessage message) async {
print(message.notification!.body != null);
if (message.notification!.body != null) {
print("=======================rideid=====================");
print(rideId);
navigatorKey.currentState?.pushNamed('/second');
}
});
SharedPreferences prefs = await SharedPreferences.getInstance();
emailAddress = prefs.getString('email').toString();
token = prefs.getString('token').toString();
emailAddress == "null" && token == "null"
? Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (context) => const PreLogin()),
(route) => false)
: role == "driver"
? Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (context) => DriverHome()),
(route) => false)
: Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (context) => const UserHome()),
(route) => false);
});
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
resizeToAvoidBottomInset: false,
body: Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage(splashBgImage),
fit: BoxFit.fill,
),
),
child: const Logo(),
)),
);
}
}
please help me to fix this issue.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的
initstate()
方法包含太多复杂的逻辑代码,需要重新格式化。特定错误
setState()在dispose()
之后调用,因为该应用已更改为另一个页面,然后调用当前页面的setState()
方法。结合上面的代码,此代码片段将应用程序更改为另一个页面,
然后在此代码代码段
调用
setState()
方法。Your
initState()
method contains too many complex logic codes and needs to be reformatted.The specific error
setState() called after dispose()
occurs because the app has changed to another page before calling thesetState()
method of the current page.Combined with the code above, this code snippet changes the app to another page
before this code snippet
which calls the
setState()
method.如果要
setState({})
匿名喜欢从提供商广播播放器侦听器回调,则必须等待窗口小部件安装,但是某个时间if(nocted){// code} {// code}
不足以执行此功能,因此会导致内存泄漏问题。解决方案是创建一个异步函数以运行您的代码并从那里设置状态。小部件的生命周期必须一直遵守。任何匿名请求对另一个小部件中的状态进行调整等待,直到安装了小部件,因此您必须延迟setState({})fotr几秒钟,然后检查窗口小部件已安装,然后设置状态。假设您使用提供商将消息设置为流订阅以设置某个状态,请说未来,您的代码看起来像这样if you want to
setState({})
anonymously like from provider broadcastStream listener callback, you must wait for your widget to be mounted, but some timeif(mounted){// your code }
isn't enough to do the trick so it will cause a memory leak problem. the solution is to create an async function to run your code and set state from there. the life cycle of a widget must be obeyed all the time. Any anonymous request to sate state in another widget wait untill that widget is mounted so you must delay setState({}) fotr a few seconds and check the widget is mounted, then set state. Lets say your using provider to set a message to a stream subscription to set a certain state lets say a future, your code would look like this