【发布时间】:2016-02-10 18:21:10
【问题描述】:
我有一个AsyncTask,当用户想要手动重新加载他的讨论消息时使用它(从我们的服务器获取用户每个讨论的 20 条最新消息)。由于某种原因,以这种方式获取的所有消息都会重复。并且每次运行任务只会创建更多重复项。第一次运行不会创建重复项,但之后的每次运行都会...值得一提的是,我使用 socket.io 与服务器通信,因此收到响应时会触发一个新线程。
讨论课
@PrimaryKey
private String discussion_id;
private RealmList<Message> messages;
// More declarations + generated getters & setters
消息类
@PrimaryKey
private String msgID;
private String message;
//Declarations + getters & setters
这是 AsyncTask 中将消息信息保存到数据库中的简化部分。
for (msgData : receivedMessages)
{
Message msg = new Message();
// Set all relevant data
realm.beginTransaction();
chat.getMessages().add(msg);
realm.copyToRealmOrUpdate(chat);
realm.commitTransaction();
}
realm.beginTransaction();
chat.setPreview(chat.getMessages().last().getMessage());
chat.setLastMessage(chat.getMessages().last().getCreated());
realm.copyToRealmOrUpdate(chat);
realm.commitTransaction();
realm.close();
我在每次调用 AsyncTask 后运行Log.d("MESSAGES TOTAL","=="+chat.getMessages().size());,这就是我得到的。
D/MESSAGES TOTAL: ==20
D/MESSAGES TOTAL: ==40
D/MESSAGES TOTAL: ==60
为了确保我跑了
String id =chat.getMessages().first().getMsgID();
long count = realm.where(Message.class).equalTo("msgID",id).count();
Log.d("FIRST ITEM ID", id+"- COUNT:"+count);
得到了
D/FIRST ITEM ID: 56bb693593de502003681054- COUNT:1
现在我陷入了如此疯狂的境地,我将聊天中的每条消息都打印到控制台并查看了 ID,这就是我发现的。
02-10 20:08:38.097 13339-13339/com.dev.proto D/DISCUSSIONACTIVITY:: CREATED: Wed Feb 10 16:45:41 EET 2016--MSG ID: 56bb693593de502003681054
02-10 20:08:38.097 13339-13339/com.dev.proto D/DISCUSSIONACTIVITY:: CREATED: Wed Feb 10 16:45:41 EET 2016--MSG ID: 56bb693593de502003681054
02-10 20:08:38.107 13339-13339/com.dev.proto D/DISCUSSIONACTIVITY:: CREATED: Wed Feb 10 16:45:41 EET 2016--MSG ID: 56bb693593de502003681054
三个相同的消息 ID。现在有些事情没有按预期工作......关于如何解决这个问题或如何进一步调试这个问题的任何想法?
【问题讨论】:
-
你从哪里得到
chat变量?另请注意,如果您执行copyOrUpdate,它也会更新您的messages列表。它通过清除它并添加所有新项目来做到这一点,但它不会删除不再在列表中的任何消息,因为它们可能会从其他地方引用。这可能是您看到重复的原因。 -
chat在循环之前从领域中检索。我将查看我用来显示结果的库。可能是我确实有RealmResult<Message>形式的引用。我会让你知道会发生什么。 -
我从未找到解决此问题的方法,但我们通过更改服务器端的更新逻辑解决了这个问题。当我有空闲时间时,我可能会仔细研究一下......
-
这都是因为这应该是一个事务,并且您应该直接为此用例创建托管对象 - 如果您使用托管 RealmList 并向其中添加托管 RealmObject,则不会重复发生。
标签: java android android-asynctask realm