首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >未处理异常:在dispose()之后调用setState()

未处理异常:在dispose()之后调用setState()
EN

Stack Overflow用户
提问于 2022-03-22 09:18:12
回答 2查看 435关注 0票数 0

我试图在我的应用程序中接收通知,使用Firebase消息将它们显示在应用程序中,但是我一直收到错误:

代码语言:javascript
复制
/FLTFireMsgReceiver( 6823): broadcast received for message
E/flutter ( 6823): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: setState() called after dispose(): _TipsState#aa4df(lifecycle state: defunct, not mounted)
E/flutter ( 6823): 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 ( 6823): 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 ( 6823): 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().
E/flutter ( 6823): #0      State.setState.<anonymous closure> (package:flutter/src/widgets/framework.dart:1085:9)
E/flutter ( 6823): #1      State.setState (package:flutter/src/widgets/framework.dart:1120:6)
E/flutter ( 6823): #2      _TipsState.getNotification.<anonymous closure> (package:stock_baba/Screens/Tips.dart:38:9)
E/flutter ( 6823): #3      _rootRunUnary (dart:async/zone.dart:1434:47)
E/flutter ( 6823): #4      _CustomZone.runUnary (dart:async/zone.dart:1335:19)
E/flutter ( 6823): #5      _CustomZone.runUnaryGuarded (dart:async/zone.dart:1244:7)
E/flutter ( 6823): #6      _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341:11)
E/flutter ( 6823): #7      _DelayedData.perform (dart:async/stream_impl.dart:591:14)
E/flutter ( 6823): #8      _StreamImplEvents.handleNext (dart:async/stream_impl.dart:706:11)
E/flutter ( 6823): #9      _PendingEvents.schedule.<anonymous closure> (dart:async/stream_impl.dart:663:7)
E/flutter ( 6823): #10     _rootRun (dart:async/zone.dart:1418:47)
E/flutter ( 6823): #11     _CustomZone.run (dart:async/zone.dart:1328:19)
E/flutter ( 6823): #12     _CustomZone.runGuarded (dart:async/zone.dart:1236:7)
E/flutter ( 6823): #13     _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1276:23)
E/flutter ( 6823): #14     _rootRun (dart:async/zone.dart:1426:13)
E/flutter ( 6823): #15     _CustomZone.run (dart:async/zone.dart:1328:19)
E/flutter ( 6823): #16     _CustomZone.runGuarded (dart:async/zone.dart:1236:7)
E/flutter ( 6823): #17     _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1276:23)
E/flutter ( 6823): #18     _microtaskLoop (dart:async/schedule_microtask.dart:40:21)
E/flutter ( 6823): #19     _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5)

PushNotification类是一个简单的类,具有字符串字段标题、正文、dataTitle和dataBody。我的代码如下:

代码语言:javascript
复制
class _TipsState extends State<Tips> {
  final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance;
  final List<PushNotification> messages = [];
  PushNotification? _notificationInfo;

  @override
  void initState() {
    getNotification();
    super.initState();
  }

  void getNotification() async {
    NotificationSettings settings =
        await _firebaseMessaging.requestPermission();

    if (settings.authorizationStatus == AuthorizationStatus.authorized) {
      print("Permission granted!");

      FirebaseMessaging.onMessage.listen((RemoteMessage message) {
        PushNotification notification = PushNotification(
            title: message.notification?.title,
            body: message.notification?.body,
            dataTitle: message.data['title'],
            dataBody: message.data['body']);

        setState(() {
          _notificationInfo = notification;
        });

        if (notification != null) {
          showSimpleNotification(Text(_notificationInfo!.title!),
              duration: Duration(seconds: 2),
              subtitle: Text(_notificationInfo!.body!));
        }
        print(notification);
        print(message.data);
      });
    } else {
      print("Permission declined!");
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: messages.isEmpty
          ? Container()
          : ListView(
              children: [Text(messages[0].title!)],
            ),
    );
  }
}

我尝试过用setState()包装我的(),但是它没有工作。

如何解决这个问题并在我的应用程序中显示传入的通知?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-03-22 10:59:43

下面是我的代码及其在工作中的..copy代码,并创建一个dart类并粘贴它。你的通知开始生效

使用那里的插件

firebase_core:^1.11.0 firebase_messaging:^11.2.5 flutter_local_notifications:^9.2.0

代码语言:javascript
复制
import 'dart:convert';
import 'dart:math';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:vcare/firebase_options.dart';

class NotificationHelper {
  NotificationDetails get _ongoing {
    const androidChannelSpecifics = AndroidNotificationDetails(
      'customer-channel-id',
      'customer-channel-name',
      importance: Importance.max,
      priority: Priority.high,
      ongoing: false,
      autoCancel: true,
    );
    const iOSChannelSpecifics = IOSNotificationDetails();
    return const NotificationDetails(android: androidChannelSpecifics, iOS: iOSChannelSpecifics);
  }

  // Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  // If you're going to use other Firebase services in the background, such as Firestore,
  // make sure you call `initializeApp` before using other Firebase services.
  // await initFirebase();
  // }

  configure() async {
    await initFirebase();
    FirebaseMessaging messaging = FirebaseMessaging.instance;
    await requestPermission(messaging);
    final String? token = await messaging.getToken();

    // FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);

    final notification = await setupLocalNotification();
    FirebaseMessaging.onMessage.listen((RemoteMessage message) {
      showNotification(
        notification,
        title: message.notification?.title,
        body: message.notification?.body,
        payload: message.data,
        type: _ongoing,
      );
    });

    return token;
  }

  Future<void> requestPermission(FirebaseMessaging messaging) async {
    await messaging.requestPermission(
      alert: true,
      announcement: false,
      badge: true,
      carPlay: false,
      criticalAlert: false,
      provisional: false,
      sound: true,
    );
  }

  Future<void> initFirebase() async {
    await Firebase.initializeApp(
      options: DefaultFirebaseOptions.currentPlatform,
    );
  }

  setupLocalNotification() async {
    const AndroidInitializationSettings initializationSettingsAndroid = AndroidInitializationSettings(
      'notification_icon',
    );
    final IOSInitializationSettings initializationSettingsIOS = IOSInitializationSettings(
      onDidReceiveLocalNotification: (int id, String? title, String? body, String? payload) {},
    );
    final InitializationSettings initializationSettings = InitializationSettings(
      android: initializationSettingsAndroid,
      iOS: initializationSettingsIOS,
    );
    var notification = FlutterLocalNotificationsPlugin();
    await notification.initialize(initializationSettings, onSelectNotification: (_) {});
    return notification;
  }

  showNotification(FlutterLocalNotificationsPlugin notifications,
      {required String? title, required String? body, required NotificationDetails type, required payload}) {
    notifications.show(Random().nextInt(100), title, body, type, payload: json.encode(payload ?? {}));
  }
}

然后在main.dart文件中调用这个类--这是代码

代码语言:javascript
复制
   WidgetsFlutterBinding.ensureInitialized();
      String? token = await NotificationHelper().configure();
    
     _storeFCMToken(token);

      print("deviceToken $token");

如果你发现任何问题,请告诉我。如果您发现此代码正在帮助您.then,请将我的答案标记为“接受”。

票数 1
EN

Stack Overflow用户

发布于 2022-03-22 09:31:54

在释放Stream后取消它

创建StreamSubscription变量

代码语言:javascript
复制
  StreamSubscription messagingSubscription;

将变量赋值给listen

代码语言:javascript
复制
....
messagingSubscription = FirebaseMessaging.onMessage.listen((RemoteMessage message) {

Dispose你的StreamSubscription

代码语言:javascript
复制
  @override
  void dispose() {
    messagingSubscription?.cancel();
    super.dispose();
  }
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71569541

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档