leancloud / LeanCloudChatKit-Android

95 stars 33 forks source link

getLastMessage 更新问题 #43

Closed daweibayu closed 7 years ago

daweibayu commented 7 years ago

我已经将android的leancloud sdk升级到3.15.7,chatkit升级到最新版本,从github更新记录来看最后更新时间是2017-01-16 15:13,最近更新中有关于一个会话最后一条消息加载的代码变更,从: updateLastMessageByConversation(conversation); 改为了: updateLastMessage(conversation.getLastMessage()); 我在更新了代码后,重新安装应用并登陆账号后无法显示会话的最后一条消息,因为conversation.getLastMessage()得到的是null。这里是否存在bug? 补充一点:我有在登陆账号后从云端查询会话记录显示在app列表中。如果用updateLastMessageByConversation就能在我登录账号后显示会话列表,并且每个会话都能看到最后一条消息,而是用更新后的updateLastMessage方法就不行。 请问是否还需要继续等待sdk更新来解决这个问题吗?还要多久?

因为APP重新安装或者登陆一个在别的设备登录过并且有会话记录的用户后,sdk是从本地数据库读取会话记录的,而本地数据库没有将云端历史会话记录拉取下来,所以这种情况下用户会显示空的会话记录。 你们有考虑将历史会话同步到本地数据库吗?何时更新这样的功能?

daweibayu commented 7 years ago

关于 conversation.getLastMessage() 是 Android sdk 的问题,已经提交代码了,明天会更新一个新版本。

ladeng commented 7 years ago

ios 的sdk有这样的方法[[LCCKConversationService sharedInstance] insertRecentConversation:con shouldRefreshWhenFinished:NO];将会话插入到本地数据库中,那么android中有类似的方法吗?我需要将云端获取下来的会话插入到数据库中。

daweibayu commented 7 years ago

这里需要分清楚的是 ChatKit 是基于 LeanCloud sdk 的,这两个并不是一个东西。 具体的 Conversation 数据的 query、缓存都是由 LeanCloud sdk 负责的,及如果调用了 AVIMConversationQuery 获取了一些 conversation,这些数据会实时缓存到 LeanCloud sdk 的缓存中的。 ChatKit 中具体展示出来的 conversation 只是因为在 LCIMConversationItemCache 中缓存了这个 conversation 的 id,LCIMConversationListFragment 会从 LCIMConversationItemCache 中看有哪些 id 被缓存了,然后再去 LeanCloud sdk 中获取元数据。 如果你想将通过 AVIMConversationQuery 拉取下来的云端数据插入到本地缓存,则可以通过调用 LCIMConversationItemCache.getInstance().insertConversation 来完成。具体相关逻辑可以查看源码。

ladeng commented 7 years ago

谢谢你的提醒,数据已经插入到数据库,但我发现一个问题,通过query接口得到的会话记录并不会根据消息更新时间倒序排列,而每次query得到的数据都不一样,所以插入数据库以后顺序就会变了,列表中的会话记录时间也不正确,没有按照会话消息的时间倒序排列,下面是我的代码,这个代码是参考ios修改得来,之前ios做这样的查询时,有得到你们同事的指导: String dateStr = "2016-01-01"; SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); Date oldTime = dateFormat.parse(dateStr);

        AVIMConversationQuery query1 = AVIMClient.getInstance(LCChatKit.getInstance().getCurrentUserId()).getQuery();
        query1.whereGreaterThanOrEqualsTo("lm",oldTime);
        query1.whereContains("m",LCChatKit.getInstance().getCurrentUserId());
        query1.limit(100);

        AVIMConversationQuery query2 = AVIMClient.getInstance(LCChatKit.getInstance().getCurrentUserId()).getQuery();
        query2.whereEqualTo("sys",true);
        query2.limit(100);

        List queryList = new ArrayList();
        queryList.add(query1);
        queryList.add(query2);

        AVIMConversationQuery query =AVIMConversationQuery.or(queryList);

        query.limit(100);
        query.findInBackground(new AVIMConversationQueryCallback(){
            @Override
            public void done(List<AVIMConversation> convs, AVIMException e) {
ladeng commented 7 years ago

补全一下我的代码: query.findInBackground(new AVIMConversationQueryCallback(){ @Override public void done(List convs, AVIMException e) { MLog.debug("session count:%d"+convs.size()); if (convs!=null){ for (AVIMConversation con : convs){ con.queryMessagesFromServer(1, new AVIMMessagesQueryCallback() { @Override public void done(List list, AVIMException e) { Log.debug("queryMessagesFromServer message:%d has error:%s",list!=null?list.size():0,e==null?"no":"yes"); } }); LCIMConversationItemCache.getInstance().insertConversation(con.getConversationId()); } //重新读取本地会话列表 updateConversationList(); } } }); }catch (Exception e){ e.printStackTrace(); }

daweibayu commented 7 years ago

具体 Android ChatKit 这边的逻辑可以查阅 LCIMConversationItemCache 代码,里边缓存的数据结构为 LCIMConversationItem,这个里边只有三个字段,conversationId、unreadCount、updateTime,排序主要是根据 updateTime 来排序的,关于 updateTime 这个具体的赋值逻辑,可以查阅源码。我这里稍后修改一下吧,在 insertConversation 时可以指定 updateTime,这样排序就不会有问题了。 具体版本应该会在下班前发出。

ladeng commented 7 years ago

嗯,这部分源码我已经看了,在插入消息时,会将插入数据的时间作为更新时间,如果返回的数据没有根据时间排序,就导致读取出来的数据顺序不对了,如果指定插入数据的时间,那这个问题应该就解决了,期待更新。

ladeng commented 7 years ago

我看到chatkit的更新了,已经将代码更新到我项目中了的,插入数据的时候我改成了这样: long updateTime = con.getUpdatedAt().getTime(); LCIMConversationItemCache.getInstance().insertConversation(con.getConversationId(),updateTime); 按道理是没问题了,但是我发现LCIMConversationItemCache中的getSortedConversationList方法存在问题,执行完sortedSet代码后应该是时间最近的显示在最顶部,但是我拿到的结果是这样的: sortedSet = {TreeSet@830052650584} size = 4 0 = {LCIMConversationItem@830047365760} conversationId = "5713a1b38ac247006472c48e" unreadCount = 0 updateTime = 1481523308120 1 = {LCIMConversationItem@830052947432} conversationId = "58492f587665216ba20149e3" unreadCount = 0 updateTime = 1481193086623 2 = {LCIMConversationItem@830051374608} conversationId = "584934637665216ba20149e6" unreadCount = 0 updateTime = 1481192567182 3 = {LCIMConversationItem@830102536344} conversationId = "58491f5a7665216ba20149e1" unreadCount = 0 updateTime = 1484738032637

前三条顺序都没问题,最后一条数据应该是显示在第一位才对,通过updateTime来对比就知道了,我有看到LCIMConversationItem中实现了排序接口,理论上那个排序接口代码是没问题的,但我的确遇到这样的排序不正确情况

daweibayu commented 7 years ago

稍等一下,昨天 debug 的时候发现点问题,我这边先把这个问题解决再发版本哈。

daweibayu commented 7 years ago

sdk 的 3.15.9 已经更新了,里边有一个问题会导致 conversation 中的数据不同步,这里已经更新了。 另外,ChatKit 1.0.7 也已经发布了,可以直接通过 insertConversation 来设置 updateTime 了。

riseLishan commented 5 years ago

现在还有问题,我用的是最新的