2026-07-01 18:25:58 +08:00

140 lines
3.6 KiB
Dart

// js_bridge.dart
import 'dart:async';
import 'dart:convert';
import 'package:webview_flutter/webview_flutter.dart';
typedef JSBridgeHandler = Future<dynamic> Function(dynamic data);
class ATJSBridge {
final Map<String, JSBridgeHandler> _handlers = {};
late WebViewController _controller;
final Map<String, Completer<dynamic>> _pendingCalls = {};
int _callId = 0;
// 初始化桥梁
void initialize(WebViewController controller) {
_controller = controller;
}
// 注册处理方法
void registerHandler(String name, JSBridgeHandler handler) {
_handlers[name] = handler;
}
// 移除处理方法
void removeHandler(String name) {
_handlers.remove(name);
}
// 调用JS方法
// 调用JS方法
Future<dynamic> callHandler(String handlerName, dynamic data) async {
final callId = 'flutter_${_callId++}_${DateTime.now().millisecondsSinceEpoch}';
final completer = Completer<dynamic>();
_pendingCalls[callId] = completer;
final message = {
'type': 'call',
'handlerName': handlerName,
'data': data,
'callId': callId,
};
try {
await _controller.runJavaScript('''
if (window.__flutterBridge && typeof window.__flutterBridge.receiveMessage === 'function') {
window.__flutterBridge.receiveMessage(${jsonEncode(message)});
} else if (window.JSBridge) {
window.JSBridge.postMessage(${jsonEncode(message)});
} else {
console.error('Flutter bridge not initialized');
}
''');
} catch (e) {
_pendingCalls.remove(callId);
completer.completeError(e);
}
// 设置超时
return completer.future.timeout(const Duration(seconds: 10), onTimeout: () {
_pendingCalls.remove(callId);
throw TimeoutException('JS call timeout');
});
}
// 处理来自JS的消息
Future<void> handleMessage(String message) async {
try {
final Map<String, dynamic> data = jsonDecode(message);
final type = data['type'] as String?;
switch (type) {
case 'call':
await _handleJSCall(data);
break;
case 'response':
await _handleJSResponse(data);
break;
default:
print('Unknown message type: $type');
}
} catch (e) {
print('Error handling message: $e');
}
}
// 处理JS调用的方法
Future<void> _handleJSCall(Map<String, dynamic> data) async {
final handlerName = data['handlerName'] as String?;
final callId = data['callId'] as String?;
final messageData = data['data'];
if (handlerName == null || callId == null) return;
dynamic result;
String? error;
try {
final handler = _handlers[handlerName];
if (handler != null) {
result = await handler(messageData);
} else {
error = 'Handler "$handlerName" not found';
}
} catch (e) {
error = e.toString();
}
// 发送响应回JS
final response = {
'type': 'response',
'callId': callId,
'data': result,
'error': error,
};
await _controller.runJavaScript('''
if (window.__flutterBridge && window.__flutterBridge.receiveResponse) {
window.__flutterBridge.receiveResponse(${jsonEncode(response)});
}
''');
}
// 处理JS的响应
Future<void> _handleJSResponse(Map<String, dynamic> data) async {
final callId = data['callId'] as String?;
if (callId == null) return;
final completer = _pendingCalls[callId];
if (completer == null) return;
if (data['error'] != null) {
completer.completeError(Exception(data['error']));
} else {
completer.complete(data['data']);
}
_pendingCalls.remove(callId);
}
}