Android 群组聊天怎么实现:基于 ZIM 的完整落地指南(附可运行 Demo)

Android 群组聊天怎么实现:基于 ZIM 的完整落地指南(附可运行 Demo)

💡 原文中文,约19500字,阅读约需47分钟。
📝

内容提要

本文介绍如何使用ZEGO ZIM SDK在Android端实现群组聊天。首先根据消息持久性和成员规模,在群组、房间、社群三种形态中选择,多数产品适合选用群组。文中给出了初始化、登录、创建群组、收发消息和会话列表的可运行示例,强调按orderKey排序,并用messageID与localMessageID去重替换。同时提醒:groupID永久不可复用;权限需在UI层校验;免打扰会话不计入总未读;切换账号前必须logout。最后简述了ZPNs离线推送的接入方法。

🔎

延伸解读

选型先于编码:群组、房间、社群不可逆

文章强调,群组、房间、社群的消息模型不同,中途换选型约等于重做。决策关键有两点:消息是否需要持久化,以及成员规模是否超过6000或需要子频道。多数产品落在群组。社群频道的conversationID与channelID不是同一个值,发消息必须用前者,否则直接失败。

groupID永久占用:设计时就要防复用

ZIM的groupID在同一AppID下全局唯一且永久不可复用,群解散后也不能再建同名群。用自增ID或业务主键当群ID,测试环境建过线上就会失败。推荐业务前缀加不可复用后缀,或留空让服务端生成并自行维护映射。后者更稳,但映射不能丢。

消息列表正确性:排序、去重、替换缺一不可

消息应按orderKey升序,而非timestamp,后者在弱网下会乱序。去重需同时比较messageID和localMessageID,只用其一会出现气泡重复或状态卡在发送中。SDK在发送状态变化、撤回、编辑时会推送新对象,因此列表操作必须是查重后替换,再统一排序,不能简单追加。

上线前容易忽略的边界:权限、未读、推送绑定

权限校验要做在UI层,且普通成员也能改群名和群公告,产品若不允许需自行禁用。免打扰会话的未读变化不会驱动总未读数,产品若坚持显示需客户端自行累加,但多端同步会失真。切换账号前必须logout,否则PushID绑定不清,会导致A用户收到B用户的消息推送。

❓

Q&A

Android 群组聊天用 ZIM SDK 实现,群组、房间、社群三种模型怎么选?

根据消息持久性和成员规模选择:消息不需要下次打开 App 还在,选房间;需要持久化且成员规模不超过 6000,选群组;成员规模超过 6000 或需要多频道,选社群(需旗舰版并联系 ZEGO 开通)。绝大多数产品适合群组。

ZIM 的 groupID 有什么限制?为什么不能直接用自增 ID 当群 ID?

groupID 在同一 AppID 下全局唯一且永久不可复用,群解散后也不能再建同名群。用自增 ID 或业务主键当群 ID,测试环境建过的 ID 线上再建会失败。推荐用“业务前缀+不可复用后缀”(如时间戳),或留空让服务端生成并自行维护业务 ID 到 groupID 的映射。

ZIM 群聊消息列表怎么排序和去重?为什么不能按 timestamp 排?

必须按 orderKey 升序排序(越大越新),因为 timestamp 是消息到达服务器的时间,网络抖动时会导致乱序。去重时优先比较 messageID,不可用时比较 localMessageID,命中则用新对象替换旧对象,而不是追加。SDK 每次消息状态变化都会推送新对象,必须替换。

ZIM 群聊的未读数统计有什么坑?免打扰会话的未读会计入总未读吗?

总未读数通过 onConversationTotalUnreadMessageCountUpdated 下发,登录后回调一次全量,之后新消息或清空未读时回调。被设为免打扰的会话,其未读变化不会驱动总未读数。如果产品要求显示免打扰未读,只能在客户端自行累加,但多端同步时会失真。

ZIM 群聊中群主想退群应该怎么操作?

群主没有直接退群的动作,必须先调用 transferGroupOwner 转让群主,成功后再调用 leaveGroup 退出。如果产品允许群主注销账号,需要在服务端编排兜底任务,自动将群主转让给最早加入的成员,否则群会永久失去管理员。

ZIM 离线推送接入时,切换账号前为什么必须 logout?

PushID 与用户是绑定关系,同一设备切换 userID 前必须先调用 zim.logout(),否则上一个用户的 PushID 绑定清不掉,会导致 A 用户收到 B 用户的消息推送。多端登录时可用 updateUserOfflinePushRule 配置哪些端接收推送。

🏷️

标签

➡️

继续阅读