Flutter中JavaScript与Dart双向通信实现方法与实践
时间:2026-08-15 | 作者:怪兽小助手 | 阅读:0基于官方 webview_flutter 插件的通信方式
这里介绍的是基于官方 webview_flutter 插件的通信方式。
在 pubspec.yaml 中添加依赖
先添加 webview 包,方便后续使用。
添加完成后,记得 pub get 更新。
dependencies:
flutter:
sdk: flutter
# 移动端 WebView 通信核心依赖
webview_flutter: ^4.4.4
# Web 平台 JS 通信依赖
js: ^0.6.7
同时还需要配置自己使用的 js 路径地址信息。
该地址位于项目根目录中,并添加对应 js 文件。
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
# To add assets to your application, add an assets section, like this:
assets:
- assets/js/xxx.js
静态 js 文件,建立通道
function test(){
if (window.FlutterJsChannel) {
window.FlutterJsChannel.postMessage(realTimeData);
console.log(realTimeData);
// 新增:打印推送成功日志
console.log("【JS 推送成功】:数据已发送给 Flutter");
} else {
// 新增:打印推送失败日志
console.log("【JS 推送失败】:FlutterJsChannel 不存在");
}
}
postMessage 通道的核心概念
- postMessage 本质是 Flutter 为 WebView 提供的跨端通信接口,专门用于 Ja vaScript → Flutter 的数据传递(单向主动推送)。
- 你可以把它理解成,Flutter 在 WebView 里“预埋”了一个名为 FlutterJsChannel(你自定义的名称)的“消息信箱”。
- JS 端只要往这个“信箱”里丢消息,也就是调用 postMessage,Flutter 端的 onMessageReceived 回调就会立刻收到并处理。
WebView 加载的 HTML/JS 中,通过 window.通道名称.postMessage(数据) 发送消息。
dart 文件创建 web 交互方法定义
通过 runJa vaScript(jsCode); 调用项目内部方法。
import 'package:webview_flutter/webview_flutter.dart';
late WebViewController _webViewController;
_webViewController = WebViewController()
..setJa vaScriptMode(Ja vaScriptMode.unrestricted)
..setBackgroundColor(Colors.white)
..loadHtmlString("""""")
..addJa vaScriptChannel(
"FlutterJsChannel",
// 实时接收 JS 传递的数据(持续回调,无需主动触发)
onMessageReceived: (Ja vaScriptMessage message) {
print("object");
// 第一步:先打印日志,这是最直接的验证,无关 UI 更新
print("【通道回调触发】:收到数据 -> ${message.message}");
// print("【数据类型】:${message.message.runtimeType}");
_updateAnimeList(message.message);
}
);
// 步骤 1:读取并加载 Assets 中的 JS 文件(核心:注入 JS 函数)
Future<void> _loadAssetsJsFile() async {
try {
// ① 读取 Assets 中的 JS 文件(转为纯文本字符串)
// 路径必须和 pubspec.yaml 中声明的一致(大小写敏感)
String assetsJsContent = await rootBundle.loadString("assets/js/md5.js");
// ② 执行该 JS 字符串,将函数注入 WebView 环境
// 此时只是「导入」函数,并未调用具体方法,无返回值
await _webViewController.runJa vaScript(assetsJsContent);
setState(() {
_callResult = "Assets JS 文件加载完成(函数已注入),可调用具体方法";
_callAssetsJsFunction();
print(_callResult);
});
} catch (e) {
setState(() {
_callResult = "加载 Assets JS 文件失败:$e";
});
}
}
// 步骤 2:调用 Assets JS 文件中定义的具体方法
_callAssetsJsFunction() async {
try {
// ① 编写 JS 代码,调用已注入的函数(来自 assets/js/demo.js)
String jsCode = """
test();
""";
// ③ 执行 JS 代码,触发函数调用
_webViewController.runJa vaScript(jsCode);
// 新增:打印日志,确认 JS 指令发送成功
print("【Flutter】JS 执行指令已发送给 WebView");
} catch (e) {
setState(() {
_callResult = "调用 Assets JS 函数失败:$e";
});
}
}
核心代码说明
-
WebViewController()
- 创建一个 WebView 的控制器实例,用来管理 WebView 的所有行为。
- 包括加载页面、JS 交互、样式设置等。
-
..setJa vaScriptMode(Ja vaScriptMode.unrestricted)
- 开启 WebView 的 Ja vaScript 支持。
- Ja vaScriptMode.unrestricted:完全允许 JS 执行,这是 Flutter 和 JS 交互的前提。
- 如果设为Ja vaScriptMode.disabled,则 WebView 中的 JS 代码无法运行,通信通道也会失效。
-
..setBackgroundColor(Colors.white)
- 设置 WebView 的背景颜色为白色。
- 默认可能是透明或灰色,这样可以优化视觉效果。
-
..loadHtmlString("""""")- 加载一段空的 HTML 字符串到 WebView 中。
- 也可以用loadUrl加载远程网页。
- 这里加载空页面,说明核心目的是通过 JS 通道接收数据,而非展示网页内容。
-
..addJa vaScriptChannel(...)
- 这是核心逻辑。它用于创建 Flutter 和 JS 之间的通信通道。
- 作用是实现JS 主动向 Flutter 发送数据。
- "FlutterJsChannel":通道的唯一标识。
- JS 端必须通过这个名称调用,比如
window.FlutterJsChannel.postMessage('要传递的数据')。 - onMessageReceived:回调函数。只要 JS 调用了postMessage,这个回调就会实时触发。
- Ja vaScriptMessage message:回调参数,message.message是 JS 传递的原始数据,字符串类型。
-
回调内的逻辑
print("【通道回调触发】:收到数据 -> ${message.message}"):打印 JS 传递的数据,用于调试验证。_updateAnimeList(message.message):调用自定义方法处理数据,比如解析数据、更新动漫列表。- 如果需要更新 Flutter 的 UI,比如把数据展示在页面上,必须用setState触发页面刷新。
项目启动类
void main()
{
WidgetsFlutterBinding.ensureInitialized();
runApp(const MyApp());
}
WidgetsFlutterBinding.ensureInitialized() 本质上就是 Flutter 应用启动时的“底层引擎预热”步骤。
先把所有 Widget 和异步任务所依赖的运行环境准备好,后面的逻辑才能顺畅接上。
Web 平台 - Dart 与 JS 通信
@JS
@JS() 是 package:js 库提供的元注解(装饰器)。
它的核心作用,是在 Dart 代码和 JS 代码之间建立映射关系。
说得直白一点,它相当于给 Dart 代码贴了一个“标识”。这个“标识”会明确告诉 Dart 编译器,这部分代码要去对应 JS 里的某个对象、函数或能力。
传递 Dart 函数给 JS(回调)
用 @allowInterop 注解(@JS() 配套),可以把 Dart 函数作为回调传给 JS。
- @JS() 是 Dart 与 Web 端 JS 交互的核心注解,用于建立 Dart 代码和 JS 变量 / 函数 / 对象的映射关系。
- 使用时必须导入 package:js,且被注解的成员需加 external 关键字。
- 配套 @allowInterop 可实现 Dart 函数作为回调传给 JS,仅支持 Web 平台。
免责声明:文中图文均来自网络,如有侵权请联系删除,心愿游戏发布此文仅为传递信息,不代表心愿游戏认同其观点或证实其描述。
相关文章
更多-
- JavaScript正则表达式批量处理HTML标签转义与替换方法
- 时间:2026-08-21
-
- JavaScript函数默认参数的精准JSDoc类型注解方法
- 时间:2026-08-21
-
- JavaScript设置Cookie的SameSite属性防范CSRF攻击
- 时间:2026-08-21
-
- JavaScript中BOM如何打开新的浏览器窗口标签
- 时间:2026-08-20
-
- JavaScript微任务队列在事件循环中的执行机制
- 时间:2026-08-20
-
- JavaScript中网络超时如何用流程控制实现中断
- 时间:2026-08-20
-
- JavaScript防抖函数原理与减少高频事件触发方法
- 时间:2026-08-20
-
- TypeScript六个颠覆认知的核心知识点解析
- 时间:2026-08-20
精选合集
更多大家都在玩
大家都在看
更多-
- 以下哪种食材被称为“地下苹果” 蚂蚁庄园今日答案9.18
- 时间:2026-09-17
-
- 蚂蚁庄园今天答题答案2026年9月18日
- 时间:2026-09-17
-
- 蚂蚁庄园答题今日答案2026年9月18日
- 时间:2026-09-17
-
- 蚂蚁庄园小课堂2026年9月18日最新题目答案
- 时间:2026-09-17
-
- 小鸡答题今天的答案是什么2026年9月18日
- 时间:2026-09-17
-
- 蚂蚁庄园每日答题答案2026年9月18日
- 时间:2026-09-17
-
- 蔬菜洗完掉色,说明是被染色了,是真的吗 蚂蚁庄园今日答案9月18日
- 时间:2026-09-17
-
- 满襟蜡绘花纹巧染就花纹当绣裳说的是哪种传统技艺 蚂蚁新村今日答案2026.9.17
- 时间:2026-09-17