Flutter使用flutter_local_notifications杀进程后点击通知无法跳转目标页
问题根因
当应用进程被终止后点击通知触发冷启动时,你现有的方案存在两个核心问题:
- 通知初始化时机太晚:你把初始化逻辑放在首页组件的
initState中,onSelectNotification回调注册完成前,应用已经完成了首页的渲染,冷启动触发的通知点击事件不会被该回调捕获 - 未处理冷启动场景的通知数据:
flutter_local_notifications中冷启动触发的通知点击数据不会走onSelectNotification回调,需要主动调用API获取
修复步骤
1. 提前初始化通知逻辑,全局绑定导航Key
将通知初始化逻辑提前到main函数中runApp执行前完成,同时定义全局NavigatorState的GlobalKey,绑定到MaterialApp中,确保任意场景下都能拿到导航实例。
代码示例:
import 'package:flutter/material.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; // 全局导航Key final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>(); final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); void main() async { WidgetsFlutterBinding.ensureInitialized(); // 提前初始化通知 await initNotification(); runApp(const MyApp()); } // 通知初始化逻辑 Future<void> initNotification() async { const AndroidInitializationSettings initializationSettingsAndroid = AndroidInitializationSettings('bolt'); const InitializationSettings initializationSettings = InitializationSettings(android: initializationSettingsAndroid); // 初始化,同时注册前台运行时的通知点击回调 await flutterLocalNotificationsPlugin.initialize( initializationSettings, onSelectNotification: selectNotification, ); // 重点:获取冷启动时的通知点击详情 final NotificationAppLaunchDetails? notificationAppLaunchDetails = await flutterLocalNotificationsPlugin.getNotificationAppLaunchDetails(); // 判断是否是点击通知冷启动 if (notificationAppLaunchDetails?.didNotificationLaunchApp ?? false) { // 等应用第一帧渲染完成后执行跳转,避免导航Key未绑定完成 WidgetsBinding.instance.addPostFrameCallback((_) { selectNotification(notificationAppLaunchDetails?.payload); }); } // 你的定时通知逻辑 const notDetails = NotificationDetails( android: AndroidNotificationDetails('1', 'Scheduled Review', channelDescription: 'Review reminders at scheduled time') ); await flutterLocalNotificationsPlugin.periodicallyShow(1, 'Scheduled Review', 'Every Minute', RepeatInterval.everyMinute, notDetails); } // 统一的通知点击跳转逻辑 Future<void> selectNotification(String? payload) async { navigatorKey.currentState?.push(MaterialPageRoute(builder: (ctx) { return Scaffold( appBar: AppBar( title: const Text('notification clicked'), ), ); })); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( // 绑定全局导航Key,不可遗漏 navigatorKey: navigatorKey, home: const HomePage(), ); } } // 你的首页组件 class HomePage extends StatelessWidget { const HomePage({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('首页')), body: const Center(child: Text('首页内容')), ); } }
2. 移除原有首页中的Noti组件
初始化逻辑已经移到main函数中,原有放在首页的通知初始化组件可以直接删除,避免重复初始化。
注意事项
- 如果有多个不同跳转目标的通知,建议在创建定时通知时传入自定义
payload,在selectNotification中根据payload判断跳转的目标页面,逻辑更灵活 - 该方案兼容
8.x和9.x版本的flutter_local_notifications库,不需要降级处理
内容的提问来源于stack exchange,提问作者kamalbanga
相关产品推荐
相关产品推荐

