Android

关注公众号 jb51net

关闭
首页 > 软件编程 > Android > Flutter中JS与Dart双向通信

Flutter中JavaScript与Dart实现双向通信的方案

作者:心之语歌

从Dart诞生之初,互操作性就是一个核心重点,下面这篇文章主要介绍了Flutter中JavaScript与Dart实现双向通信方案的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下

基于官方 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 通道的核心概念

WebView 加载的 HTML/JS 中,通过 window.通道名称.postMessage(数据) 发送消息

dart 文件 创建 web 交互 方法定义

通过 runJavaScript(jsCode); 调用项目 内部方法

import 'package:webview_flutter/webview_flutter.dart';
late WebViewController _webViewController;
_webViewController = WebViewController()
	..setJavaScriptMode(JavaScriptMode.unrestricted)
	..setBackgroundColor(Colors.white)
	..loadHtmlString("""<html><body></body></html>""")
	..addJavaScriptChannel(
		"FlutterJsChannel",
		// 实时接收 JS 传递的数据(持续回调,无需主动触发)
		onMessageReceived: (JavaScriptMessage 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.runJavaScript(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.runJavaScript(jsCode);
	  // 新增:打印日志,确认 JS 指令发送成功
	  print("【Flutter】JS 执行指令已发送给 WebView");
	} catch (e) {
	  setState(() {
	    _callResult = "调用 Assets JS 函数失败:$e";
	  });
	}
}

项目启动类

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。

总结 

到此这篇关于Flutter中JavaScript与Dart实现双向通信方案的文章就介绍到这了,更多相关Flutter中JS与Dart双向通信内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文