
1. 插件介绍
JS-Dart通信桥接组件是一个专为OpenHarmony平台优化的Flutter插件,用于实现JavaScript(WebView)与Dart(Flutter)之间的双向通信。该组件提供了一套完整的通信机制,支持异步调用、回调处理和错误管理,适用于需要在Flutter应用中嵌入Web内容并实现复杂交互的场景。
核心功能
- 支持JS调用Dart方法并获取返回值
- 支持Dart调用JS方法并获取返回值
- 提供异步通信机制
- 完整的错误处理流程
- 支持参数和返回值的序列化与反序列化
- 与OpenHarmony WebView完美集成
2. 环境设置
在使用该组件之前,需要确保开发环境满足以下要求:
Flutter环境
- Flutter SDK: ≥2.19.6
- Dart SDK: ≥2.19.6
OpenHarmony环境
- OpenHarmony SDK API: ≥9
- DevEco Studio: ≥3.0
项目配置
确保项目已正确配置OpenHarmony开发环境,并已创建Flutter for OpenHarmony项目。
3. 包的引入
由于该组件是自定义修改版本,需要以git形式通过AtomGit引入。在项目的pubspec.yaml文件中添加以下依赖:
yaml
dependencies:
flutter:
sdk: flutter
webview_flutter:
git:
url: "https://atomgit.com/openharmony-tpc/flutter_packages.git"
path: "packages/webview_flutter/webview_flutter"
然后运行以下命令安装依赖:
bash
flutter pub get
4. API调用与使用示例
4.1 WebView初始化
首先,需要初始化WebView并配置JavaScript支持:
dart
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'js_bridge.dart';
class WebPage extends StatefulWidget {
const WebPage({Key? key}) : super(key: key);
@override
State<WebPage> createState() => _WebPageState();
}
class _WebPageState extends State<WebPage> {
late WebViewController controller;
final JSBridge _jsBridge = JSBridge();
@override
void initState() {
super.initState();
_initWebView();
_initJsBridge();
Future.delayed(const Duration(seconds: 1), () {
controller.loadFlutterAsset("assets/html/index.html");
});
}
_initWebView() async {
controller = WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted)
..addJavaScriptChannel(
JSBridge.name,
onMessageReceived: (JavaScriptMessage message) {
_jsBridge.receiverMessage(message.message);
},
)
..setNavigationDelegate(NavigationDelegate(
onUrlChange: (change) {
_jsBridge.injectBridgeJS(controller);
},
));
}
_initJsBridge() {
_jsBridge.messageExecutor = controller.runJavaScript;
// 注册Dart方法供JS调用
_jsBridge.register("getToken", (data, callback) {
print("JS调用了getToken方法,参数:$data");
// 模拟异步操作
Future.delayed(const Duration(seconds: 1), () {
callback("flutter_token_123"); // 返回结果给JS
});
});
}
// 其他代码...
}
4.2 JS调用Dart方法
在HTML页面中,通过注入的bridge对象调用Dart方法:
html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
</head>
<body>
<p id="demo">WebView Content</p>
<button type="button" onclick="jsCallAsync()">调用Dart方法</button>
<script>
async function jsCallAsync() {
var param = { "userId": "12345" };
let result = await window.bridge.call("getToken", param);
document.getElementById("demo").innerHTML = "从Dart获取的Token: " + result;
}
</script>
</body>
</html>
4.3 Dart调用JS方法
在Dart代码中,通过JSBridge调用JS方法:
dart
_callJsMethod() {
var param = {"userName": "flutter_user"};
_jsBridge.call(
"userInfo",
param,
callback: (responseData) {
print("JS返回结果: $responseData");
setState(() {
message = "JS返回结果: $responseData";
});
},
errorCallback: (errorMessage) {
print("调用JS方法出错: $errorMessage");
},
);
}
4.4 JS注册方法供Dart调用
在JS代码中注册方法供Dart调用:
javascript
// 注册JS方法
window.bridge.register("userInfo", function(data, callback) {
console.log("Dart调用了userInfo方法,参数:", data);
var result = { "name": "JS User", "id": "js_123" };
callback(result); // 返回结果给Dart
});
5. 资源配置
5.1 添加本地HTML和JS文件
将HTML和JS文件放在项目的assets目录下:
assets/
├── html/
│ └── index.html
└── js/
└── bridge.js
5.2 配置pubspec.yaml
在pubspec.yaml文件中配置资源路径:
yaml
flutter:
assets:
- assets/html/
- assets/js/
5.3 OpenHarmony权限配置
在ohos/entry/src/main/module.json5文件中添加网络权限(如果需要加载远程内容):
json5
{
"module": {
"name": "entry",
"type": "entry",
"description": "...",
"mainElement": "...",
"deviceTypes": ["phone", "tablet"],
"distro": {
"deliveryWithInstall": true,
"moduleName": "entry",
"moduleType": "entry"
},
"abilities": [...],
"requestPermissions": [
{
"name": "ohos.permission.INTERNET"
}
]
}
}
6. 完整示例
6.1 Dart端完整代码
dart
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'js_bridge.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'JS-Dart Bridge Demo',
theme: ThemeData(primarySwatch: Colors.blue),
home: const WebPage(),
);
}
}
class WebPage extends StatefulWidget {
const WebPage({Key? key}) : super(key: key);
@override
State<WebPage> createState() => _WebPageState();
}
class _WebPageState extends State<WebPage> {
late WebViewController controller;
String message = "初始化中...";
final JSBridge _jsBridge = JSBridge();
@override
void initState() {
super.initState();
_initWebView();
_initJsBridge();
Future.delayed(const Duration(seconds: 1), () {
controller.loadFlutterAsset("assets/html/index.html");
});
}
_initWebView() async {
controller = WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted)
..addJavaScriptChannel(
"flutterObj",
onMessageReceived: (JavaScriptMessage message) {
setState(() {
this.message = message.message;
});
},
)
..addJavaScriptChannel(
JSBridge.name,
onMessageReceived: (JavaScriptMessage message) {
_jsBridge.receiverMessage(message.message);
},
)
..setNavigationDelegate(NavigationDelegate(
onUrlChange: (change) {
_jsBridge.injectBridgeJS(controller);
},
));
}
_initJsBridge() {
_jsBridge.messageExecutor = controller.runJavaScript;
_jsBridge.register("getToken", (data, callback) {
print("JS调用了getToken方法,参数:$data");
Future.delayed(const Duration(seconds: 1), () {
callback("flutter_token_123");
});
});
_jsBridge.register("testCallback", (data, callback) {
print("JS调用了testCallback方法,参数:$data");
});
}
_callJsBridge() {
var param = {"userName": "flutter_user"};
_jsBridge.call(
"userInfo",
param,
callback: (responseData) {
setState(() {
message = "JS返回结果: $responseData";
});
},
errorCallback: (errorMessage) {
setState(() {
message = "调用JS方法出错: $errorMessage";
});
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('JS-Dart Bridge Demo')),
body: Column(children: [
ElevatedButton(
onPressed: () => _callJsBridge(),
child: const Text("调用JS方法"),
),
Text(message),
Expanded(
child: WebViewWidget(controller: controller),
)
]),
);
}
}
6.2 HTML端完整代码
html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
</head>
<body>
<p id="demo">WebView Content</p>
<button type="button" onclick="callFlutterFunction()">发送消息给Flutter</button>
<button type="button" onclick="jsCallAsync()">调用Dart方法</button>
<script>
var count = 0;
function callFlutterFunction() {
flutterObj.postMessage('JS 调用了 Flutter ' + (++count));
}
async function jsCallAsync() {
var param = { "userId": "12345" };
let result = await window.bridge.call("getToken", param);
document.getElementById("demo").innerHTML = "从Dart获取的Token: " + result;
}
// 注册JS方法供Dart调用
window.bridge.register("userInfo", function(data, callback) {
console.log("Dart调用了userInfo方法,参数:", data);
var result = { "name": "JS User", "id": "js_123" };
callback(result);
});
</script>
</body>
</html>
7. 总结
JS-Dart通信桥接组件为OpenHarmony平台上的Flutter应用提供了强大的WebView与Flutter通信能力。该组件支持双向通信、异步调用、回调处理和错误管理,适用于需要在Flutter应用中嵌入Web内容并实现复杂交互的场景。
通过本指南,您可以快速了解该组件的使用方法,包括环境设置、包的引入、API调用和完整示例。该组件已经过OpenHarmony平台优化,确保在OpenHarmony设备上稳定运行。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net