FlutterBridge监听修改一对多
This commit is contained in:
@@ -4,6 +4,7 @@ import 'dart:html' as html;
|
||||
|
||||
import 'package:js/js.dart';
|
||||
import 'package:web_tools/utils/model/model.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
// h5交互通知 原生 {type:'enum',data:'所需参数,可无'}
|
||||
enum ToFlutterAppEnum {
|
||||
@@ -105,18 +106,15 @@ enum WebInteractionType {
|
||||
taskKeyOtherPage('TaskKeyOtherPage'), // 其他页面
|
||||
taskKeyMineBackpack('TaskKeyMineBackpack'), // 我的装扮背包页面(或者是称号)
|
||||
taskKeyMineWallet('TaskKeyMineWallet'), // 我的钱包页面
|
||||
unknown('unknown'),
|
||||
;
|
||||
unknown('unknown');
|
||||
|
||||
const WebInteractionType(
|
||||
this.code,
|
||||
);
|
||||
const WebInteractionType(this.code);
|
||||
final String code; //服务端 key
|
||||
|
||||
factory WebInteractionType.fromCode(String? code) => values.firstWhere(
|
||||
(element) => element.code == code,
|
||||
orElse: () => WebInteractionType.unknown,
|
||||
);
|
||||
(element) => element.code == code,
|
||||
orElse: () => WebInteractionType.unknown,
|
||||
);
|
||||
}
|
||||
|
||||
// 原生交互通知 h5 {type:'enum',data:'所需参数 '}
|
||||
@@ -146,7 +144,9 @@ class FlutterBridge {
|
||||
// 取消监听 'translateResult' 类型的消息
|
||||
FlutterBridge.instance.off(FromJsEnum.translateResult.code);
|
||||
* */
|
||||
final _messageListeners = <String, Function(Map<String, dynamic>)>{};
|
||||
// final _messageListeners = <String, Function(Map<String, dynamic>)>{};
|
||||
// 1. 修改这里:Value 从 Function 变成 List<Function>
|
||||
final _messageListeners = <String, List<Function(Map<String, dynamic>)>>{};
|
||||
var textMap = <String, String>{}; //多语言翻译
|
||||
|
||||
FlutterBridge._internal() {
|
||||
@@ -160,8 +160,19 @@ class FlutterBridge {
|
||||
try {
|
||||
final Map<String, dynamic> data = jsonDecode(event.data);
|
||||
final String? type = data['type'];
|
||||
// 找到监听列表,遍历调用
|
||||
if (type != null && _messageListeners.containsKey(type)) {
|
||||
_messageListeners[type]?.call(data);
|
||||
final listeners = _messageListeners[type];
|
||||
if (listeners != null && listeners.isNotEmpty) {
|
||||
// 使用 List.from 浅拷贝一份进行遍历,防止在回调中移除监听导致并发修改异常
|
||||
for (final callback in List.from(listeners)) {
|
||||
try {
|
||||
callback(data); // 这里的 data 是已经解析好的 Map
|
||||
} catch (e) {
|
||||
print("Error in listener callback: $e");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
print('Invalid message format from Flutter: $type');
|
||||
} catch (e) {
|
||||
@@ -170,8 +181,19 @@ class FlutterBridge {
|
||||
} else {
|
||||
try {
|
||||
final String? type = event.data['type'];
|
||||
// 找到监听列表,遍历调用
|
||||
if (type != null && _messageListeners.containsKey(type)) {
|
||||
_messageListeners[type]?.call(event.data);
|
||||
final listeners = _messageListeners[type];
|
||||
if (listeners != null && listeners.isNotEmpty) {
|
||||
// 使用 List.from 浅拷贝一份进行遍历,防止在回调中移除监听导致并发修改异常
|
||||
for (final callback in List.from(listeners)) {
|
||||
try {
|
||||
callback(event.data); // 这里的 data 是已经解析好的 Map
|
||||
} catch (e) {
|
||||
print("Error in listener callback: $e");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
print('Invalid message format from Flutter: $type');
|
||||
} catch (e) {
|
||||
@@ -181,24 +203,56 @@ class FlutterBridge {
|
||||
});
|
||||
}
|
||||
|
||||
// 注册监听某个 type 的消息
|
||||
void on(String type, Function(Map<String, dynamic>) callback) {
|
||||
if (_messageListeners.containsKey(type)) {
|
||||
print("Listener for '$type' is already registered.");
|
||||
return; // 如果已经注册了这个类型的监听器,就不再重复添加
|
||||
}
|
||||
_messageListeners[type] = callback;
|
||||
print("Listener for '$type' has been registered.");
|
||||
/// 仅监听一次,触发后自动移除
|
||||
void once(String type, Function(Map<String, dynamic>) callback) {
|
||||
// 定义一个引用,用于在回调内部取消自己
|
||||
VoidCallback? cancelRef;
|
||||
|
||||
// 注册监听
|
||||
cancelRef = on(type, (data) {
|
||||
// 1. 立即移除监听
|
||||
cancelRef?.call();
|
||||
|
||||
// 2. 执行真正的业务回调
|
||||
callback(data);
|
||||
});
|
||||
}
|
||||
|
||||
// 取消监听某个 type 的消息
|
||||
void off(String type) {
|
||||
/// 3. 核心修改:on 方法
|
||||
/// 返回一个 VoidCallback,调用它即可取消本次监听
|
||||
VoidCallback on(String type, Function(Map<String, dynamic>) callback) {
|
||||
if (!_messageListeners.containsKey(type)) {
|
||||
print("No listener found for '$type'.");
|
||||
return; // 如果没有找到监听器,直接返回
|
||||
_messageListeners[type] = [];
|
||||
}
|
||||
|
||||
_messageListeners[type]!.add(callback);
|
||||
print(
|
||||
"Listener added for '$type'. Total listeners: ${_messageListeners[type]!.length}",
|
||||
);
|
||||
|
||||
// 返回一个闭包,用于精确移除当前的 callback
|
||||
return () {
|
||||
if (_messageListeners.containsKey(type)) {
|
||||
_messageListeners[type]?.remove(callback);
|
||||
print(
|
||||
"One listener removed for '$type'. Remaining: ${_messageListeners[type]?.length}",
|
||||
);
|
||||
|
||||
// 如果该类型没有监听者了,可以选择清理 key
|
||||
if (_messageListeners[type]!.isEmpty) {
|
||||
_messageListeners.remove(type);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// 4. 兼容旧代码的 off 方法
|
||||
/// 警告:这会移除该类型下的【所有】监听器
|
||||
void off(String type) {
|
||||
if (_messageListeners.containsKey(type)) {
|
||||
_messageListeners.remove(type);
|
||||
print("All listeners for '$type' have been removed.");
|
||||
}
|
||||
_messageListeners.remove(type);
|
||||
print("Listener for '$type' has been removed.");
|
||||
}
|
||||
|
||||
// 发送消息给 App(通过 WebView 调用 JS 方法)
|
||||
@@ -238,29 +292,34 @@ class FlutterBridge {
|
||||
void toRecharge() => sendToFlutter(ToFlutterAppEnum.toRecharge.code, {});
|
||||
void toRedDiamond() => sendToFlutter(ToFlutterAppEnum.toRedDiamond.code, {});
|
||||
void jumpToH5(String path, String title) => sendToFlutter(
|
||||
ToFlutterAppEnum.jumpToH5.code, {'path': path, 'title': title});
|
||||
ToFlutterAppEnum.jumpToH5.code,
|
||||
{'path': path, 'title': title},
|
||||
);
|
||||
void toHomepage(String userId) =>
|
||||
sendToFlutter(ToFlutterAppEnum.toHomepage.code, {'userId': userId});
|
||||
void toMonthCardPay(String googleProductId, String iosProductId,
|
||||
{otherUserId = ''}) =>
|
||||
sendToFlutter(ToFlutterAppEnum.toMonthCardPay.code, {
|
||||
'googleProductId': googleProductId,
|
||||
'iosProductId': iosProductId,
|
||||
'otherUserId': otherUserId,
|
||||
});
|
||||
void toMonthCardPay(
|
||||
String googleProductId,
|
||||
String iosProductId, {
|
||||
otherUserId = '',
|
||||
}) => sendToFlutter(ToFlutterAppEnum.toMonthCardPay.code, {
|
||||
'googleProductId': googleProductId,
|
||||
'iosProductId': iosProductId,
|
||||
'otherUserId': otherUserId,
|
||||
});
|
||||
void checkGameState(String gameCode) => sendToFlutter(
|
||||
ToFlutterAppEnum.checkGameState.code, {'gameCode': gameCode});
|
||||
ToFlutterAppEnum.checkGameState.code,
|
||||
{'gameCode': gameCode},
|
||||
);
|
||||
|
||||
void share({
|
||||
required String activityId, // 活动id
|
||||
required bool needShareReport, // 是否需要上报分享数据
|
||||
ShareCardModel? shareCardModel, // 分享上方卡片 数据,参考客户端参数
|
||||
}) =>
|
||||
sendToFlutter(ToFlutterAppEnum.share.code, {
|
||||
"activityId": activityId,
|
||||
"shareReportKey": needShareReport ? "ActivityShared" : "",
|
||||
...shareCardModel?.toJson() ?? {},
|
||||
});
|
||||
}) => sendToFlutter(ToFlutterAppEnum.share.code, {
|
||||
"activityId": activityId,
|
||||
"shareReportKey": needShareReport ? "ActivityShared" : "",
|
||||
...shareCardModel?.toJson() ?? {},
|
||||
});
|
||||
|
||||
//专属见面礼
|
||||
void taskInviteCodeGift() =>
|
||||
@@ -268,14 +327,19 @@ class FlutterBridge {
|
||||
|
||||
//解析 URL 并跳转
|
||||
void taskCommandJump({required String scheme, required String activityId}) =>
|
||||
sendToFlutter(ToFlutterAppEnum.showCommandJump.code,
|
||||
{"scheme": scheme, "activityId": activityId});
|
||||
sendToFlutter(ToFlutterAppEnum.showCommandJump.code, {
|
||||
"scheme": scheme,
|
||||
"activityId": activityId,
|
||||
});
|
||||
|
||||
//跳转至网页
|
||||
void taskToWebViewPage(
|
||||
{required String linkUrl, required String activityId}) =>
|
||||
sendToFlutter(ToFlutterAppEnum.showToWebViewPage.code,
|
||||
{"linkUrl": linkUrl, "activityId": activityId});
|
||||
void taskToWebViewPage({
|
||||
required String linkUrl,
|
||||
required String activityId,
|
||||
}) => sendToFlutter(ToFlutterAppEnum.showToWebViewPage.code, {
|
||||
"linkUrl": linkUrl,
|
||||
"activityId": activityId,
|
||||
});
|
||||
|
||||
void checkStartBroadcaster() =>
|
||||
sendToFlutter(ToFlutterAppEnum.checkStartBroadcaster.code, {});
|
||||
@@ -296,7 +360,7 @@ class FlutterBridge {
|
||||
/** 在直播间或聊天室停留观看n分钟 */
|
||||
void shouldWatchDuration() =>
|
||||
sendToFlutter(ToFlutterAppEnum.shouldWatchDuration.code, {});
|
||||
/** 在直播间或聊天室发送n条公屏消息 */
|
||||
/** 在直播间或聊天室发送n条公屏消息 */
|
||||
void shouldSendPublicMessage() =>
|
||||
sendToFlutter(ToFlutterAppEnum.shouldSendPublicMessage.code, {});
|
||||
/** 在直播间或聊天室上麦互动n分钟 */
|
||||
@@ -311,7 +375,7 @@ class FlutterBridge {
|
||||
/** 分享n次直播间或聊天室至任意平台 */
|
||||
void shouldShareRoom() =>
|
||||
sendToFlutter(ToFlutterAppEnum.shouldShareRoom.code, {});
|
||||
/** 佩戴任意装扮 */
|
||||
/** 佩戴任意装扮 */
|
||||
void shouldWearDecoration() =>
|
||||
sendToFlutter(ToFlutterAppEnum.shouldWearDecoration.code, {});
|
||||
/** 前往语音房 */
|
||||
|
||||
Reference in New Issue
Block a user