与APP交互回调添加队列方法sendRequest

This commit is contained in:
zhulixiao
2026-01-27 17:25:20 +08:00
parent cbd3d8eff8
commit 587af2c22a
2 changed files with 170 additions and 115 deletions

View File

@@ -131,6 +131,15 @@ enum FromFlutterAppEnum {
@JS()
external void sendMessageToNative(String data);
/// 🆕 [新增] 通用请求任务模型
class _RequestTask {
final String sendType; // 发送给 Native 的类型
final Map<String, dynamic> params; // 发送的参数
final Function(Map<String, dynamic>) callback; // 成功回调
_RequestTask(this.sendType, this.params, this.callback);
}
class FlutterBridge {
static final FlutterBridge instance = FlutterBridge._internal();
@@ -139,6 +148,12 @@ class FlutterBridge {
final _messageListeners = <String, List<Function(Map<String, dynamic>)>>{};
var textMap = <String, String>{}; //多语言翻译
/// 🆕 [新增] 通用请求队列池 (Key: listenType, Value: 任务列表)
final Map<String, List<_RequestTask>> _requestQueues = {};
/// 🆕 [新增] 忙碌状态池 (记录哪些 listenType 当前正在等待 Native 回复)
final Set<String> _activeResponseTypes = {};
FlutterBridge._internal() {
_initListener();
}
@@ -193,21 +208,6 @@ class FlutterBridge {
});
}
/// 仅监听一次,触发后自动移除
void once(String type, Function(Map<String, dynamic>) callback) {
// 定义一个引用,用于在回调内部取消自己
VoidCallback? cancelRef;
// 注册监听
cancelRef = on(type, (data) {
// 1. 立即移除监听
cancelRef?.call();
// 2. 执行真正的业务回调
callback(data);
});
}
/// 3. 核心修改on 方法
/// 返回一个 VoidCallback调用它即可取消本次监听
VoidCallback on(String type, Function(Map<String, dynamic>) callback) {
@@ -236,14 +236,86 @@ class FlutterBridge {
};
}
/// 4. 兼容旧代码的 off 方法
/// 警告:这会移除该类型下的【所有】监听器
/// 警告:这会移除该类型下的【所有】监听器 (慎用,通常用于全局重置,一旦调用,该 type 别的地方监听器将失效)
void off(String type) {
if (_messageListeners.containsKey(type)) {
_messageListeners.remove(type);
print("All listeners for '$type' have been removed.");
}
}
// =========================================================
// 👇 🆕 [新增] 核心通用请求方法 (替代了旧的 requestTranslate)
// =========================================================
/// 发送请求并等待回调 (自动排队,防并发)
/// [sendType] 发送给 Native 的类型
/// [listenType] 等待 Native 回复的类型
/// [params] 参数
/// [onSuccess] 成功回调
void sendRequest({
required ToFlutterAppEnum sendType,
required FromFlutterAppEnum listenType,
required Map<String, dynamic> params,
required Function(Map<String, dynamic>) onSuccess,
}) {
final responseKey = listenType.code;
// 1. 初始化该类型的队列
if (!_requestQueues.containsKey(responseKey)) {
_requestQueues[responseKey] = [];
}
// 2. 入队
_requestQueues[responseKey]!.add(_RequestTask(
sendType.code,
params,
onSuccess,
));
// 3. 调度执行
_processRequestQueue(responseKey);
}
/// 🆕 [新增] 内部队列调度方法
void _processRequestQueue(String responseKey) {
// 如果该类型正在忙,或者队列空了,直接返回
if (_activeResponseTypes.contains(responseKey) ||
(_requestQueues[responseKey]?.isEmpty ?? true)) {
return;
}
// 1. 标记忙碌
_activeResponseTypes.add(responseKey);
// 2. 取出队首任务
final task = _requestQueues[responseKey]!.removeAt(0);
// 3. 注册临时监听 (使用 on 的多播特性)
VoidCallback? cancelRef;
cancelRef = on(responseKey, (data) {
try {
final innerData = data['data'] ?? {};
// 执行业务回调
task.callback(innerData);
} catch (e) {
print("Queue processing error: $e");
} finally {
// --- 任务闭环 ---
// A. 移除当前临时监听 (不影响全局监听)
cancelRef?.call();
// B. 解除忙碌状态
_activeResponseTypes.remove(responseKey);
// C. 递归处理下一个任务
_processRequestQueue(responseKey);
}
});
// 4. 发送 Native 消息
sendToFlutter(task.sendType, task.params);
}
// 发送消息给 App通过 WebView 调用 JS 方法)
void sendToFlutter(String type, Map<String, dynamic> data) {
@@ -277,8 +349,8 @@ class FlutterBridge {
sendToFlutter(ToFlutterAppEnum.createGame.code, {'gameId': gameId});
void wantToPlay(String gameId) =>
sendToFlutter(ToFlutterAppEnum.wantToPlay.code, {'gameId': gameId});
void translateRequest(Map<String, String> data) =>
sendToFlutter(ToFlutterAppEnum.translateRequest.code, data);
// void translateRequest(Map<String, String> data) =>
// sendToFlutter(ToFlutterAppEnum.translateRequest.code, data);//移除建议使用sendRequest方法
void toRecharge() => sendToFlutter(ToFlutterAppEnum.toRecharge.code, {});
void toRedDiamond() => sendToFlutter(ToFlutterAppEnum.toRedDiamond.code, {});
void jumpToH5(String path, String title) => sendToFlutter(