--- title: 接收消息 --- # 接收消息 开发者拦截 SDK 接收的消息,并进行相应的业务操作。 ## 消息接收监听器说明 {#listener} SDK 提供了消息接收监听器 [OnReceiveMessageWrapperListener],可接收实时消息或离线消息。 当客户端连接成功后,服务端会将所有离线消息?以消息包(Package)的形式下发给客户端,每个 Package 中最多含 200 条消息。客户端会解析 Package 中的消息,逐条上抛并通知应用。 SDK 接收到消息时会触发以下方法。 ```java public boolean onReceived(Message message, int left, boolean hasPackage, boolean offline) ``` - `left` 为当前正在解析的消息包(Package)中还剩余的消息条数。 - `hasPackage` 表示当前是否在服务端还存在未下发的消息包(Package)。 - `offline` 表示当前消息是否为离线消息。 同时满足以下条件,表示离线消息已收取完毕: - `hasPackage` 为 `false`:表示当前正在解析最后一包消息。 - `left` 为 0:表示最后一个消息包中最后一条消息已接收完毕。 从 5.2.3 版本开始,每次连接成功后,离线消息收取完毕时会触发以下回调方法。如果没有离线消息,连接成功后会立即触发。 ```java public void onOfflineMessageSyncCompleted() { // } ``` ## 设置消息接收监听器 IMKit SDK 在 [IMCenter](https://doc.rongcloud.cn/apidoc/imkit-android/latest/zh_CN/html/-android--i-m-kit--s-d-k/io.rong.imkit/-i-m-center/index.html) 类中提供了 `addOnReceiveMessageListener`/ `removeOnReceiveMessageListener` 方法,支持设置多个消息接收监听器。 ### 添加消息监听器 设置消息接收监听器。所有接收到的消息都会在此接口方法中回调。建议在应用生命周期内注册消息监听。请注意不要重复添加,避免内存泄露。 调用 [IMCenter](https://doc.rongcloud.cn/apidoc/imkit-android/latest/zh_CN/html/-android--i-m-kit--s-d-k/io.rong.imkit/-i-m-center/index.html) 类 `addOnReceiveMessageListener` 设置消息接收监听器,回调线程的情况如下: - 如果 SDK 版本 = 5.3.3,`onReceivedMessage` 回调在非主线程中。 - 如果 SDK 版本 ≦ 5.3.2 或 ≧ 5.3.4,`onReceivedMessage` 回调在主线程中。 ```java IMCenter.getInstance().addOnReceiveMessageListener( new RongIMClient.OnReceiveMessageWrapperListener() { @Override public boolean onReceived(Message message, int left, boolean hasPackage, boolean offline) { return false; } }); ``` ### 移除消息监听器 SDK 支持移除监听器。为了避免内存泄露,请在不需要监听时将监听器移除。 ```java IMCenter.getInstance().removeOnReceiveMessageListener(listener); ``` ## 设置异步消息接收监听器 :::tip IMKit 从 5.3.4 开始提供以下接口,并且 IMKit SDK 默认使用 `addAsyncOnReceiveMessageListener`。 ::: IMKit SDK 在 [IMCenter](https://doc.rongcloud.cn/apidoc/imkit-android/latest/zh_CN/html/-android--i-m-kit--s-d-k/io.rong.imkit/-i-m-center/index.html) 类中提供了 `addAsyncOnReceiveMessageListener`/ `removeAsyncOnReceiveMessageListener` 方法,支持设置多个消息接收监听器。 ### 添加异步消息监听器 如果 SDK 版本 ≧ 5.3.4,可调用 [IMCenter](https://doc.rongcloud.cn/apidoc/imkit-android/latest/zh_CN/html/-android--i-m-kit--s-d-k/io.rong.imkit/-i-m-center/index.html) 类的 `addAsyncOnReceiveMessageListener` 设置消息接收监听器,`onReceivedMessage` 回调在非主线程中。所有接收到的消息都会在此接口方法中回调。建议在应用生命周期内注册消息监听。请注意不要重复添加,避免内存泄露。 ```java IMCenter.getInstance().addAsyncOnReceiveMessageListener( new RongIMClient.OnReceiveMessageWrapperListener() { @Override public boolean onReceived(Message message, int left, boolean hasPackage, boolean offline) { return false; } }); ``` ### 移除异步消息监听器 如果 SDK 版本 ≧ 5.3.4,可调用 [IMCenter](https://doc.rongcloud.cn/apidoc/imkit-android/latest/zh_CN/html/-android--i-m-kit--s-d-k/io.rong.imkit/-i-m-center/index.html) 类 `removeAsyncOnReceiveMessageListener` 移除监听器。为了避免内存泄露,请在不需要监听时将监听器移除。 ```java IMCenter.getInstance().removeAsyncOnReceiveMessageListener(listener); ``` ## 禁用排重机制 消息排重机制会在 SDK 接收单聊、群聊、系统消息时自动去除内容重复消息。当 App 本地存在大量消息,SDK 默认的排重机制可能会因性能问题导致收消息卡顿。因此在接收消息发生卡顿问题时,App 可以尝试禁用 SDK 的排重机制。 ### 为什么接收消息可能出现消息重复 发送端处于弱网情况下可能出现该问题。A 向 B 发送消息后,消息成功到达服务端,并成功下发到接收者 B。但 A 由于网络等原因可能未收到服务端返回的 ack,导致 A 认为没有发送成功。此时如果 A 重发消息(IMKit 默认具有失败自动重发机制,建议同时关闭),此时 B 就会收到与之前重复的消息(消息内容相同,但 Message UID 不同)。 ```mermaid sequenceDiagram autonumber Note over UserA, RongCloudServer: 发送端处于弱网情况 UserA ->> RongCloudServer: 发送消息 RongCloudServer --x UserA: 弱网情况未返回回执 RongCloudServer ->> UserB: 下发消息 UserA ->> RongCloudServer: 重新发送消息 RongCloudServer -->> UserA: 返回回执 RongCloudServer ->> UserB: 下发消息 ``` ### 关闭消息排重机制 单聊、群聊、系统消息使用 IMLib 的核心类 [RongCoreClient](https://doc.rongcloud.cn/apidoc/imlibcore-android/latest/zh_CN/html/-android--i-m-lib-core--s-d-k/io.rong.imlib/-rong-core-client/index.html) 中的 `setCheckDuplicateMessage` 方法(要求 SDK 版本 ≧ 5.3.4),禁用消息排重行为。请在 SDK 初始化之后,建立 IM 连接之前完成以下配置: ```java boolean enableCheck = false // 关闭消息排重 RongCoreClient.getInstance().setCheckDuplicateMessage(enableCheck) ``` > 聊天室消息从 5.8.2 版本开始支持关闭消息排重。在 `RongChatRoomClient` 中提供。 请在 SDK 初始化之后,建立 IM 连接之前调用。多次调用以最后一次为准。 ```java boolean enableCheck = false // 关闭消息排重 RongChatRoomClient.getInstance().setCheckChatRoomDuplicateMessage(enableCheck) ``` ### 关闭失败重发机制 IMKit SDK 默认启用了消息失败自动重发机制。在禁用消息排重机制后,为避免收到 UID 重复的消息,建议同时在 App 中禁用 IMKit 的失败重发机制。 请在 SDK 初始化之后,建立 IM 连接之前完成以下配置: ```java RongConfigCenter.conversationConfig().rc_enable_resend_message = false; ``` [OnReceiveMessageWrapperListener]: https://doc.rongcloud.cn/apidoc/imlib-android/latest/zh_CN/html/-android--i-m-lib--s-d-k/io.rong.imlib/-rong-i-m-client/-on-receive-message-wrapper-listener/index.html [Message]: https://doc.rongcloud.cn/apidoc/imlibcore-android/latest/zh_CN/html/-android--i-m-lib-core--s-d-k/io.rong.imlib.model/-message/index.html