Flutter中WebView加载OneSignal通知附加链接失效问题求助
看起来你遇到的问题是flutter_webview_plugin的WebviewScaffold不会自动响应url变量的状态更新,导致点击推送后还是显示初始的谷歌页面。我来帮你调整代码解决这个问题:
问题根源
你当前的代码只通过setState更新了url变量,但WebviewScaffold组件的url参数是初始化时传入的,后续状态变更不会触发它重新加载新链接。另外,你也没有处理附加数据为空的边界情况,可能引发潜在崩溃。
修复步骤
1. 引入WebView插件实例主动控制加载
首先在状态类中创建FlutterWebviewPlugin实例,这样可以主动调用方法让WebView加载新URL:
final flutterWebviewPlugin = FlutterWebviewPlugin();
然后在通知打开的回调中,不仅更新url变量,还要主动调用reloadUrl方法触发WebView加载新链接:
OneSignal.shared.setNotificationOpenedHandler((OSNotificationOpenedResult result) { // 安全获取附加链接,避免空指针 final String? targetUrl = result.notification.payload.additionalData?['url']?.toString(); if (targetUrl != null && targetUrl.isNotEmpty) { setState(() { url = targetUrl; }); // 主动让WebView加载新地址 flutterWebviewPlugin.reloadUrl(targetUrl); } });
2. 处理附加数据为空的情况
一定要对additionalData和其中的url做空判断,避免因为推送数据缺失导致应用崩溃,上面的代码已经包含了这个逻辑。
3. 调整OneSignal初始化顺序(推荐)
建议先完成OneSignal的初始化,再绑定通知回调,确保SDK初始化完成后再监听事件:
// 先初始化OneSignal await OneSignal.shared.init("你的App ID", iOSSettings: settings); // 再设置通知处理回调 OneSignal.shared.setNotificationReceivedHandler(...); OneSignal.shared.setNotificationOpenedHandler(...);
4. 清理资源避免内存泄漏
在页面销毁时记得销毁WebView插件实例:
@override void dispose() { flutterWebviewPlugin.dispose(); super.dispose(); }
完整修改后的代码
import 'package:flutter/material.dart'; import 'dart:async'; import 'package:flutter_webview_plugin/flutter_webview_plugin.dart'; import 'package:onesignal/onesignal.dart'; void main() => runApp(new MyApp()); class MyApp extends StatefulWidget { @override _MyAppState createState() => new _MyAppState(); } class _MyAppState extends State<MyApp> { String _debugLabelString = ""; String url = "https://www.google.com"; final flutterWebviewPlugin = FlutterWebviewPlugin(); bool _requireConsent = false; @override void initState() { super.initState(); initPlatformState(); } Future<void> initPlatformState() async { if (!mounted) return; OneSignal.shared.setLogLevel(OSLogLevel.verbose, OSLogLevel.none); OneSignal.shared.setRequiresUserPrivacyConsent(_requireConsent); var settings = { OSiOSSettings.autoPrompt: false, OSiOSSettings.promptBeforeOpeningPushUrl: true }; // 先初始化OneSignal SDK await OneSignal.shared .init("086d22bd-5539-4849-9db2-01589fd3429d", iOSSettings: settings); OneSignal.shared .setInFocusDisplayType(OSNotificationDisplayType.notification); // 前台接收通知时的处理(可选) OneSignal.shared.setNotificationReceivedHandler((notification) { final String? targetUrl = notification.payload.additionalData?['url']?.toString(); if (targetUrl != null && targetUrl.isNotEmpty) { setState(() { url = targetUrl; }); flutterWebviewPlugin.reloadUrl(targetUrl); } }); // 点击通知时的处理 OneSignal.shared .setNotificationOpenedHandler((OSNotificationOpenedResult result) { final String? targetUrl = result.notification.payload.additionalData?['url']?.toString(); if (targetUrl != null && targetUrl.isNotEmpty) { setState(() { url = targetUrl; }); flutterWebviewPlugin.reloadUrl(targetUrl); } }); } @override void dispose() { flutterWebviewPlugin.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return new MaterialApp( home: new Scaffold( appBar: new AppBar( title: const Text('OneSignal Flutter Demo'), backgroundColor: Color.fromARGB(255, 212, 86, 83), ), body: WebviewScaffold( url: url, withJavascript: true, ) ), ); } }
内容的提问来源于stack exchange,提问作者Ghost
相关产品推荐
相关产品推荐

