Flutter Awesome Notifications:点击操作按钮取消进度条通知
Flutter端实现FCM通知操作按钮取消通知的方案
完全可以在Flutter端实现需求,不需要写原生代码。核心思路是避开Isolate访问变量的限制,利用Awesome Notifications的原生API和Isolate通信机制来解决:
直接用Awesome Notifications API取消通知
不管当前代码在哪个Isolate里,AwesomeNotifications().cancel(notificationId)这个方法都是全局可用的。只要你在创建通知时给每条通知分配了唯一的id(可以在FCM消息的data字段里携带,或者本地生成),在_actionHandler里拿到这个id就能直接调用取消方法,不需要依赖timers变量。解决timer停止的问题
如果你的进度条是用Timer来更新的,由于Isolate无法直接访问主Isolate的timers集合,可以通过Isolate通信来触发主Isolate停止对应timer:- 在主Isolate里注册一个全局的ReceivePort,用来接收来自其他Isolate的信号:
final ReceivePort _receivePort = ReceivePort(); final Map<int, Timer> _timers = {}; // 存储通知ID对应的timer void main() { // 给端口命名,方便其他Isolate查找 IsolateNameServer.registerPortWithName(_receivePort.sendPort, 'notification_timer_port'); _receivePort.listen((message) { if (message is Map && message['action'] == 'cancel_timer') { final int notificationId = message['id']; _timers[notificationId]?.cancel(); _timers.remove(notificationId); } }); runApp(MyApp()); } - 在_actionHandler里,取消通知后,通过命名端口找到主Isolate的SendPort,发送停止timer的信号:
Future<void> _actionHandler(ReceivedAction receivedAction) async { if (receivedAction.actionType == ActionType.Default) { final int notificationId = receivedAction.id!; // 先取消通知 await AwesomeNotifications().cancel(notificationId); // 通知主Isolate停止对应timer final SendPort? sendPort = IsolateNameServer.lookupPortByName('notification_timer_port'); sendPort?.send({ 'action': 'cancel_timer', 'id': notificationId }); } }
- 在主Isolate里注册一个全局的ReceivePort,用来接收来自其他Isolate的信号:
这样就完美解决了Isolate无法访问timers的问题,所有逻辑都在Flutter端完成,不需要介入原生代码。
内容的提问来源于stack exchange,提问作者이동헌
相关产品推荐
相关产品推荐

