// js_bridge.dart import 'dart:async'; import 'dart:convert'; import 'package:webview_flutter/webview_flutter.dart'; typedef JSBridgeHandler = Future Function(dynamic data); class ATJSBridge { final Map _handlers = {}; late WebViewController _controller; final Map> _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 callHandler(String handlerName, dynamic data) async { final callId = 'flutter_${_callId++}_${DateTime.now().millisecondsSinceEpoch}'; final completer = Completer(); _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 handleMessage(String message) async { try { final Map 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 _handleJSCall(Map 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 _handleJSResponse(Map 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); } }