Flutter本地通知崩溃:StandardMethodCodec.decodeEnvelope报错排查
Flutter本地通知崩溃:Missing type parameter错误排查与修复
在Flutter应用中集成本地通知功能后,Firebase Crashlytics捕获到崩溃,核心报错为Missing type parameter,关联StandardMethodCodec.decodeEnvelope方法。以下是问题代码、错误堆栈及修复方案。
错误堆栈信息
Fatal Exception: io.flutter.plugins.firebase.crashlytics.FlutterError: PlatformException(error, Missing type parameter., null, java.lang.RuntimeException: Missing type parameter. at g.c.d.T.a.<init>(:3) at com.dexterous.flutterlocalnotifications.c.<init>(Unknown Source:0) at com.dexterous.flutterlocalnotifications.FlutterLocalNotificationsPlugin.loadScheduledNotifications(Unknown Source:25) at com.dexterous.flutterlocalnotifications.FlutterLocalNotificationsPlugin.removeNotificationFromCache(Unknown Source:0) at com.dexterous.flutterlocalnotifications.FlutterLocalNotificationsPlugin.cancelNotification(Unknown Source:53) at com.dexterous.flutterlocalnotifications.FlutterLocalNotificationsPlugin.cancel(:2) at com.dexterous.flutterlocalnotifications.FlutterLocalNotificationsPlugin.onMethodCall(Unknown Source:389) at j.a.e.a.y.a(Unknown Source:17) at io.flutter.embedding.engine.n.q.i(Unknown Source:11) at io.flutter.embedding.engine.n.q.j(:3) at io.flutter.embedding.engine.n.c.run(Unknown Source:12) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:233) at android.os.Looper.loop(Looper.java:344) at android.app.ActivityThread.main(ActivityThread.java:8205) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:589) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1071) ). Error thrown null. at StandardMethodCodec.decodeEnvelope(message_codecs.dart:607) at MethodChannel._invokeMethod(platform_channel.dart:177) at FlutterLocalNotificationsPlugin.cancel(flutter_local_notifications_plugin.dart:274)
Fatal Exception: java.lang.RuntimeException: Unable to start receiver com.dexterous.flutterlocalnotifications.ScheduledNotificationReceiver: java.lang.RuntimeException: Missing type parameter. at android.app.ActivityThread.handleReceiver(ActivityThread.java:4890) at android.app.ActivityThread.-$$Nest$mhandleReceiver(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2417) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loopOnce(Looper.java:226) at android.os.Looper.loop(Looper.java:313) at android.app.ActivityThread.main(ActivityThread.java:8741) at java.lang.reflect.Method.invoke(Method.java) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067)
原实现代码
@override void initState() { // TODO: implement initState super.initState(); check_notification(); } check_notification()async{ FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); if(toggle_notification==false){ _flutterLocalNotificationsPlugin.cancelAll; } else{ intialize(); ScheduledNotification_remove(); } } final _localNotificationService = FlutterLocalNotificationsPlugin(); Future<void> intialize() async { tz.initializeTimeZones(); const AndroidInitializationSettings androidInitializationSettings = AndroidInitializationSettings('@drawable/ic_launcher'); final DarwinInitializationSettings initializationSettingsDarwin = DarwinInitializationSettings( onDidReceiveLocalNotification: onDidReceiveLocalNotification, requestSoundPermission: true, requestBadgePermission: true, requestAlertPermission: true, ); final InitializationSettings settings = InitializationSettings( android: androidInitializationSettings, iOS: initializationSettingsDarwin, ); await _localNotificationService.initialize( settings, // onSelectNotification: onSelectNotification, ); } Future<NotificationDetails> _notificationDetails() async { const AndroidNotificationDetails androidNotificationDetails = AndroidNotificationDetails('channel_id', 'channel_name', channelDescription: 'description', importance: Importance.max, priority: Priority.high, enableVibration: true, playSound: true ); const DarwinNotificationDetails darwinNotificationDetails = DarwinNotificationDetails( presentSound: true, presentAlert: true, presentBadge: true); return NotificationDetails( android: androidNotificationDetails, iOS: darwinNotificationDetails, ); } Future<void> showScheduledNotification( {required int id, required String title, required String body, required int seconds}) async { final details = await _notificationDetails(); await _localNotificationService.zonedSchedule( id, title, body, tz.TZDateTime.from( DateTime.now().add(Duration(seconds: seconds)), tz.local, ), details, androidAllowWhileIdle: true, uiLocalNotificationDateInterpretation: UILocalNotificationDateInterpretation.absoluteTime, ); } ScheduledNotification_remove()async{ final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); _flutterLocalNotificationsPlugin.cancel(1); _flutterLocalNotificationsPlugin.cancel(2); _flutterLocalNotificationsPlugin.cancel(3); _flutterLocalNotificationsPlugin.cancel(4); _flutterLocalNotificationsPlugin.cancel(5); showScheduledNotification( id: 1, title: 'title1', body: "body1", seconds: 1, } showScheduledNotification( id: 2, title: 'title2', body: "body2", seconds: 2, } showScheduledNotification( id: 3, title: 'title3', body: "body3", seconds: 3, } showScheduledNotification( id: 4, title: 'title4', body: "body4", seconds: 4, } showScheduledNotification( id: 5, title: 'title5', body: "body5", seconds: 5, } }
问题排查与修复
崩溃核心原因是代码存在异步调用未等待、语法错误及插件未初始化完成就执行操作的问题,具体修复点如下:
- 异步调用未加await:所有异步方法(
initialize、cancel、cancelAll、showScheduledNotification)调用时必须添加await,确保操作完成后再执行后续逻辑,避免平台层状态不一致。 - 语法错误:
cancelAll缺少方法调用括号,应为cancelAll();所有showScheduledNotification调用末尾错误使用},需改为);。 - 重复创建插件实例:多次创建
FlutterLocalNotificationsPlugin实例会导致状态混乱,统一使用全局的_localNotificationService实例即可。
修正后的核心代码片段
@override void initState() { super.initState(); check_notification(); } // 全局统一插件实例 final _localNotificationService = FlutterLocalNotificationsPlugin(); check_notification()async{ if(toggle_notification==false){ await _localNotificationService.cancelAll(); } else{ await intialize(); await ScheduledNotification_remove(); } } ScheduledNotification_remove()async{ await _localNotificationService.cancel(1); await _localNotificationService.cancel(2); await _localNotificationService.cancel(3); await _localNotificationService.cancel(4); await _localNotificationService.cancel(5); await showScheduledNotification( id: 1, title: 'title1', body: "body1", seconds: 1, ); await showScheduledNotification( id: 2, title: 'title2', body: "body2", seconds: 2, ); await showScheduledNotification( id: 3, title: 'title3', body: "body3", seconds: 3, ); await showScheduledNotification( id: 4, title: 'title4', body: "body4", seconds: 4, ); await showScheduledNotification( id: 5, title: 'title5', body: "body5", seconds: 5, ); }
内容的提问来源于stack exchange,提问作者Nitneuq
相关产品推荐
相关产品推荐

