tencent cloud

文档反馈

Android & iOS & Mac

最后更新时间:2023-01-29 16:10:44

    功能描述

    用户在登录 App 后,可以展示最近会话列表,方便找到目标会话。

    会话列表功能主要分为获取会话列表、处理会话列表更新。
    本文将为您介绍具体的实现细节。

    获取会话列表基础接口

    您可以调用 getConversationList(Android / iOS & Mac / Windows) 获取会话列表。该接口拉取的是本地缓存的会话,如果服务器会话有更新,SDK 内部会自动同步,然后在 V2TIMConversationListener 回调告知客户。

    用户的会话以列表的形式返回,列表中存储的是 V2TIMConversation 对象。目前 IM SDK 对会话列表的排序规则为:

    • 5.5.892 及以后版本, 获取的会话列表默认已经按照会话对象的 orderKey 做了排序。orderKey 值越大,代表该会话排序越靠前。orderKey 字段是整型数,当发送新消息、接收新消息、设置草稿或置顶会话时,会话被激活,orderKey 字段会增大。
    • 5.5.892 以前版本,获取的会话列表默认已经按照会话 lastMessage -> timestamp 做了排序。timestamp 越大,会话越靠前。
    注意:

    在某些场景下,可能出现会话的 lastMessage 为空(例如清空会话消息)。如果您使用 5.5.892 以前的 SDK,使用 lastMessage 排序时需要额外处理这种异常。我们建议您升级到 5.5.892 及以后的版本,使用 orderKey 字段排序。

    您可以使用 getConversationList 实现一次性拉取或分页拉取。参考下文说明。

    一次性拉取

    一次性拉取适合会话数量比较少的情况(100 个以内)。此时可以将拉取的 count 设置为 INT_MAX(一般会话数量不会达到 INT_MAX 这么多)。

    示例代码如下:

    V2TIMManager.getConversationManager().getConversationList(0, Integer.MAX_VALUE, new V2TIMValueCallback<V2TIMConversationResult>() {
       @Override
       public void onSuccess(V2TIMConversationResult v2TIMConversationResult) {
           long nextSeq = v2TIMConversationResult.getNextSeq();
           Log.i("imsdk", "success nextSeq:" + nextSeq + ", isFinish:" + v2TIMConversationResult.isFinished());
            List<V2TIMConversation> v2TIMConversationList = v2TIMConversationResult.getConversationList();
           for (V2TIMConversation v2TIMConversation : v2TIMConversationList) {
               Log.i("imsdk", "success showName:" + v2TIMConversation.getShowName());
           }
       }
        @Override
       public void onError(int code, String desc) {
           Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);
       }
    });
    

    分页拉取

    如果您的应用场景会产生较多的会话数,考虑到加载效率、网络省流,我们建议您采用分页拉取的方式。每次分页拉取的数量建议不超过 100 个。

    分页拉取的步骤:

    1. 首次调用 getConversationList 时,指定参数 nextSeq 为 0(表示从头开始拉取会话列表),指定 count 为 50(表示一次拉取 50 个会话对象)。

    2. 首次拉取会话列表成功后,getConversationList 的回调结果 V2TIMConversationResult 中会包含 nextSeq(下次分页拉取的字段)、isFinish(会话拉取是否完成)。

      • 如果 isFinishedtrue,表示所有会话已经拉取完成。
      • 如果 isFinishedfalse,表示还有更多的会话可以拉取。此时并不意味着要立刻开始拉取 “下一页” 的会话列表。在常见的软件中,分页拉取通常由用户的滑动操作触发的,用户每上拉一次会话列表就触发一次分页拉取。
    3. 当用户继续上拉会话列表时,如果还有更多的会话可以拉取,可以继续调用 getConversationList 接口,并传入新一轮的 nextSeq(数值来自上一次拉取返回的 V2TIMConversationResult 对象)和 count 参数。

    4. 重复执行【步骤 3】直至 isFinished 返回 true。

    示例代码如下:

    V2TIMManager.getConversationManager().getConversationList(0, 20, new V2TIMValueCallback<V2TIMConversationResult>() {
       @Override
       public void onSuccess(V2TIMConversationResult v2TIMConversationResult) {
           long nextSeq = v2TIMConversationResult.getNextSeq();
           Log.i("imsdk", "success nextSeq:" + nextSeq + ", isFinish:" + v2TIMConversationResult.isFinished());
            List<V2TIMConversation> v2TIMConversationList = v2TIMConversationResult.getConversationList();
           for (V2TIMConversation v2TIMConversation : v2TIMConversationList) {
               Log.i("imsdk", "success showName:" + v2TIMConversation.getShowName());
           }
            if (!v2TIMConversationResult.isFinished()) {
               getConversationListInternal(nextSeq, 20);
           }
       }
        @Override
       public void onError(int code, String desc) {
           Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);
       }
    });
    

    获取会话列表高级接口

    如果以上的普通接口无法满足您对拉取会话列表的需求,我们还提供了高级接口 getConversationListByFilter (Android / iOS & Mac / Windows),其中拉取会话的 V2TIMConversationListFilter 详解如下:

    属性 含义 说明
    type 会话类型 C2C 或者群组会话
    nextSeq 分页拉取的游标 第一次拉取传 0,后续分页拉取传入上一次成功拉取返回的 nextSeq
    count 分页拉取的个数 一次分页建议不超过 100
    markType 会话标记类型 参考文档 会话标记
    groupName 会话分组名称 不是群组名称,是会话分组的名称,参考文档 会话分组

    示例代码如下:

    V2TIMConversationListFilter filter = new V2TIMConversationListFilter();
    filter.setConversationType(V2TIMConversation.V2TIM_C2C);
    filter.setMarkType(V2TIMConversation.V2TIM_CONVERSATION_MARK_TYPE_STAR);
    filter.setGroupName("conversation_group");
    filter.setCount(50);
    filter.setNextSeq(0);
    V2TIMManager.getConversationManager().getConversationListByFilter(filter, new V2TIMValueCallback<V2TIMConversationResult>() {
       @Override
       public void onSuccess(V2TIMConversationResult v2TIMConversationResult) {
           // 获取会话列表成功
       }
        @Override
       public void onError(int code, String desc) {
           // 获取会话列表失败
       }
    });
    

    会话列表更新

    IM SDK 会在登录成功后、用户上线后、以及断线重连后,自动更新会话列表。
    为了获取会话列表的更新,您需要操作如下几步:

    1. 添加会话监听器。
    2. 接收会话变更通知并处理。
    3. 移除会话监听器。非必须,可按照业务逻辑按需调用。

    添加会话监听器

    您可以调用 addConversationListener(Android / iOS & Mac / Windows) 添加会话监听器。添加监听器后,您才能接收到会话变更事件。

    示例代码如下:

    V2TIMManager.getConversationManager().addConversationListener(conversationListener);
    

    会话新增变更通知

    您可以在 V2TIMConversationListener(Android / iOS & Mac / Windows) 中的事件,获取会话列表变更的通知。

    目前 IM SDK 支持的会话变更事件有:

    事件 说明 建议
    onSyncServerStart 同步服务器会话开始 SDK 会在登录成功、用户上线、断网重连后自动同步服务器会话,您可以监听这个事件做一些 UI 进度展示操作。
    onSyncServerFinish 同步服务器会话完成 如果会话有变更,会通过 onNewConversation/onConversationChanged 回调告知。
    onSyncServerFailed 同步服务器会话失败 您可以监听这个事件做一些 UI 异常展示操作。
    onNewConversation 有会话新增 例如收到一个新同事发来的单聊消息、被拉入了一个新的群组中等,此时可以重新对会话列表做排序。
    onConversationChanged 有会话更新 例如未读计数发生变化、最后一条消息被更新等,此时可以重新对会话列表做排序。
    onTotalUnreadMessageCountChanged 会话未读总数变更通知 详情请参考 会话未读数。5.3.425 及以上版本支持。
    注意:

    1. 为保证会话列表顺序符合最后一条消息的排序原则,每次会话变更/新增后,您需要对数据源重新排序。
    • 如果您使用 5.5.892 以前的版本,可以使用 lastMessage 排序,但是需要注意处理 lastMessage 为空(例如清空会话消息)的情况。
    • 如果您使用 5.5.892 及以后的版本,使用 orderKey 字段排序。我们强烈建议您升级到 5.5.892 及以后版本。
    1. 调用 getConversationList 接口拉取的会话可能已经通过 onNewConversation 回调接口添加到了 UI 会话列表的数据源中。为了避免重复添加同一个会话,您需要在 UI 会话列表数据源中根据 getConversationID 找到相同的会话并做替换。

    示例代码如下:

    // 监听会话的回调
    V2TIMConversationListener conversationListener = new V2TIMConversationListener() {
       @Override
       public void onSyncServerStart() {
           Log.i("imsdk", "onSyncServerStart");
       }
        @Override
       public void onSyncServerFinish() {
           Log.i("imsdk", "onSyncServerFinish");
       }
        @Override
       public void onSyncServerFailed() {
           Log.i("imsdk", "onSyncServerFailed");
       }
        @Override
       public void onNewConversation(List<V2TIMConversation> conversationList) {
           Log.i("imsdk", "onNewConversation");
       }
        @Override
       public void onConversationChanged(List<V2TIMConversation> conversationList) {
           Log.i("imsdk", "onConversationChanged");
       }
        @Override
       public void onTotalUnreadMessageCountChanged(long totalUnreadCount) {
           Log.i("imsdk", "onTotalUnreadMessageCountChanged");
       }
    };
    

    移除会话监听器

    您可以调用 removeConversationListener(Android / iOS & Mac / Windows) 移除会话监听器。移除后,您将无法再接收到会话变更事件。
    该步骤不是必须的,您可以按照自己的业务逻辑按需调用。

    示例代码如下:

    V2TIMManager.getConversationManager().removeConversationListener(conversationListener);
    

    发送不更新 lastMessage 的消息

    会话列表界面,通常需要展示每个会话的最新一条消息预览及发送时间,此时您可以使用 V2TIMConversationlastMessage 作为数据源实现。
    但是某些场景下,如果您不希望一些消息(例如系统提示等)显示为会话的最新消息,可以在 sendMessage 时设置 isExcludedFromLastMessagefalse/NO

    发送消息 sendMessage 的使用参考:发送消息

    说明:

    isExcludedFromLastMessage 参数仅增强版 SDK 5.4.666 及以上版本支持。

    示例代码如下:

    // 创建消息对象
    V2TIMMessage v2TIMMessage = V2TIMManager.getMessageManager().createTextMessage(content);
    // 设置不更新会话 lastMessage
    v2TIMMessage.setExcludedFromLastMessage(true);
    // 发送消息
    V2TIMManager.getMessageManager().sendMessage(v2TIMMessage, "userID", null, V2TIMMessage.V2TIM_PRIORITY_DEFAULT, false, null, new V2TIMSendCallback<V2TIMMessage>() {
       @Override
       public void onSuccess(V2TIMMessage v2TIMMessage) {
           Log.i("imsdk", "success");
       }
        @Override
       public void onProgress(int progress) {
           Log.i("imsdk", "progress:" + progress);
       }
        @Override
       public void onError(int code, String desc) {
           Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);
       }
    });
    

    联系我们

    联系我们,为您的业务提供专属服务。

    技术支持

    如果你想寻求进一步的帮助,通过工单与我们进行联络。我们提供7x24的工单服务。

    7x24 电话支持