对聊天消息进行排序的方法

最近的项目用到了即时通讯相关的SDK ,并且有加载聊天记录的需求,目前我的方法是把UI显示与数据库导入分开操作,但发现在存在消息的情况下,会将历史消息加载在原有新消息的下方,并会导致重复加载,

Tip: 重复加载历史消息在之前就遇到过,我是通过自建数据库判断是否存在相同msgId来实现的.

所以,只能在内存中对消息进行排序,让消息以正确的顺序显示来实现.以下为实现代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/**
* 获取所有消息
*
* @param messages
*/
private List<EMMessage> loadMessagesWithMsgTime(EMMessage[] messages) {
List<Pair<Long, EMMessage>> sortList = new ArrayList<>();
/**
* 如果在排序过程中有新消息收到,lastMsgTime会发生变化
* 影响排序过程,Collection.sort会产生异常
* 保证Conversation在Sort过程中最后一条消息的时间不变
* 避免并发问题
**/
synchronized (messages) {
for (EMMessage message : messages) {
sortList.add(new Pair<>(message.getMsgTime(), message));
}
}
try {
sortMessagesByMsgTime(sortList);
} catch (Exception e) {
e.printStackTrace();
}
List<EMMessage> list = new ArrayList<>();
for (Pair<Long, EMMessage> sortItem : sortList) {
list.add(sortItem.second);
}
return list;
}
/**
* 对消息排序
*
* @param messageList
*/
private void sortMessagesByMsgTime(List<Pair<Long, EMMessage>> messageList) {
Collections.sort(messageList, new Comparator<Pair<Long, EMMessage>>() {
@Override
public int compare(Pair<Long, EMMessage> con1, Pair<Long, EMMessage> con2) {
if (con1.first == con2.first) {
return 0;
} else if (con2.first < con1.first) {
return 1;
} else {
return -1;
}
}
});
}

以下为排序方法的调用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* 刷新列表
**/
private void refreshList() {
// UI线程不能直接使用conversation.getAllMessages()
// 否则在UI刷新过程中,如果收到新的消息,会导致并发问题
messages = (EMMessage[]) conversation.getAllMessages().toArray(new EMMessage[conversation.getAllMessages().size()]);
List<EMMessage> list = loadMessagesWithMsgTime(messages);
if (list.size() != 0) {
messages = (EMMessage[]) list.toArray(new EMMessage[list.size()]);
for (int i = 0; i < messages.length; i++) {
//获得会话指定位置的消息
conversation.getMessage(i);
}
notifyDataSetChanged();
}
}