用途
本技能用于在 Flutter 应用中响应 CometChat 的活动,即处理“消息到达时做某事”“更新角标计数”“群组变化时刷新屏幕”“cometchat listener”等 Kit 组件自身行为之外的响应式需求。
两套事件系统
资料明确指出存在两套事件系统,且它们不可互换:
- SDK 监听器:来源是服务器,通过 CometChat.* 注册,使用 CometChat.addMessageListener(id, this),对应 Mixin 为 MessageListener、CallListener、UserListener、GroupListener、ConnectionListener,回答“服务器说发生了 X”,适用于角标、推送、来电、分析。
- UI Kit 事件:来源是 Kit 自身的组件,通过 CometChatMessageEvents.addMessagesListener(id, this) 注册,对应 Mixin 为 CometChatMessageEventListener、CometChatGroupEventListener、CometChatUserEventListener、CometChatConversationEventListener,回答“用户在 Kit 中做了 X”,适用于响应 Kit 操作(如从输入框发送消息、通过 Kit 退出群组)。
是否需要监听器
Kit 的组件本身已是实时的:CometChatConversations 会自行更新未读数,CometChatMessageList 会追加收到的消息,CometChatMessageHeader 会显示正在输入和在线状态,这些都不需要额外监听器。只有当需求超出 Kit 表面时才添加监听器,例如应用级角标、分析钩子、推送注册、来电时导航。资料特别指出,为了“让列表更新”而添加监听器是最常见的错误,因为它本身就会更新。
使用方式
SDK 监听器示例:在 State 中混入 MessageListener,定义静态监听器 id,在 initState 中调用 CometChat.addMessageListener(_id, this),在 dispose 中调用 CometChat.removeMessageListener(_id),并实现 onTextMessageReceived 等回调。
UI Kit 事件示例:在 State 中混入 CometChatMessageEventListener,在 initState 中调用 CometChatMessageEvents.addMessagesListener(_id, this),在 dispose 中调用 CometChatMessageEvents.removeMessagesListener(_id)。
监听器生命周期规则
- 在 initState 注册,在 dispose 移除,始终成对出现。
- 每个屏幕使用唯一、稳定的监听器 id;跨屏幕复用同一 id 会导致后注册的静默替换先注册的。
- 在 Flutter 中移除尤为重要:热重启和路由重新进入都会重新执行 initState,未移除的监听器会再次触发,导致角标重复计数、来电弹窗打开两次。
- 登录后再注册;登录解析前添加的监听器收不到任何事件。
编译陷阱
不要在同一类中混用两个消息监听器:MessageListener(SDK)与 CometChatMessageEventListener(UI Kit)都声明了 onCardMessageReceived,但使用两个不同的 CardMessage 类型(一个来自 cometchat_sdk,一个来自 Kit)。在同一 State 上混用会导致编译失败,报 invalid_override。需要同时使用时,应使用两个独立的类(或两个 State)。
常见陷阱
- 为让 Kit 组件更新而添加监听器——它本身就会更新。
- 未在 dispose 中移除,导致热重启或重新进入后事件重复。
- 共享监听器 id,导致一个屏幕静默注销另一个屏幕。
- 在同一类中混用两个消息 Mixin,导致无法编译。
- 登录前注册,导致无事件。
- 期望用 UI 事件接收服务器活动(或反之),应根据表格选择正确的系统。
- v5 事件 API:v5 的 DataSource/ChatConfigurator 事件管线已移除(参见迁移相关内容)。
验证方式
确认每次事件只触发一次(而非两次);热重启应用后确认仍只触发一次;离开再返回确认没有重复;应用在后台时,返回后服务器端事件仍能到达。
前置与安装
前置条件与安装由 cometchat-flutter-v6-core 覆盖,本技能不引入新包。资料建议先阅读 cometchat-flutter-v6-core(安装、凭据、init→login→render),本技能假定已完成该步骤。