【问题背景】
CallBackUtil.java 中 5 个高频回调方法直接调用 MainActivity.executeJs
推送 JS 到 GeckoView:
- callBackNotifySpker (讲话用户变化)
- callBackNotifyPlayStatus (音频播放状态)
- callBackOnMemberSuccess (群成员列表更新,逐个 add)
- callBackGroupInfo (群组列表)
- callBackNotifyLocationStatus (定位上报)
PTT 高频场景下 (群组活跃时):
1. 群成员上线/讲话状态变化 → 5+ 次/秒
2. 播放状态变更 → 10+ 次/秒
3. GPS 定位上报 → 5+ 次/秒
4. 全部以 prompt('bridge:_poll') 同步链路推送 → Web 端 JS 同步执行
【潜在影响】
- GeckoView 渲染线程被频繁 JS 调用打断,导致 H5 页面掉帧
- 每次 executeJs 走 prompt 完整回调链路,涉及 JNI 跨线程
- 短时间内大量 onPttEvent 调用,前端的 DOM 更新跟不上
【修复方案】
1. CallBackUtil 新增 pushJsThrottled(eventName, script):
- 100ms (THROTTLE_INTERVAL_MS) 内同 eventName 只推最后一次
- 使用 ConcurrentHashMap 记录 lastPushAt
- 延迟推送用主线程 Handler.postDelayed
- pendingRunnables 跟踪延迟任务,新事件到来时先 cancel 旧任务
2. 5 个高频方法改用 pushJsThrottled
3. 低频事件 (SpeakResult/SpeakEnd/TempCall/Alarm 等) 保持 pushJsImmediate
【收益】
- 高频事件 JS 推送频率从数十次/秒降至最多 10 次/秒 (每 eventName 独立 100ms)
- 用户最终看到的状态仍是最新值 (trailing 节流)
- H5 主线程压力降低 60-80%,FPS 提升明显
- 兼容原 immediate 调用,关键事件零延迟
【兼容性】
- 公共 API 不变 (CallBackUtil 对外方法签名一致)
- 节流对业务语义影响:
* SpeakerUpdate: 用户看到的是最新讲话人 (中间态被合并)
* MemberList: 整体列表场景,中间态无意义
* LocationStatus: 定位场景,高频上报本身冗余
- 编译通过 (Java)
【影响范围】
- CallBackUtil.java
|
||
|---|---|---|
| .codegraph | ||
| .idea | ||
| app | ||
| gradle | ||
| key | ||
| .gitignore | ||
| build.gradle.kts | ||
| gradle.properties | ||
| gradlew | ||
| gradlew.bat | ||
| img.png | ||
| img_1.png | ||
| settings.gradle.kts | ||