至此发现了一个bug,有时候发一条消息会没有反应,然后多发几次刷出来一大串。调试进去看看发现设计上的失误。
updateMessage是异 步调用,成功后应该更新。但是由于是异步调用有可能出现这种情况,调用updateMessage,参数发出去了,在返回之前,又调用了一次,这时 lastIndex还没有更新,自然就会读出重复的信息。
于是我加了一个标记变量,调用updateMessage之后把isUpdating设 为true,以免再次调用,然后再onSuccess最后置回false
private boolean isUpdating = false;
private void update() {
if (clientId == -1) {
initClientId();
} else {
if (!isUpdating) {
isUpdating = true;
service.updateMessage(clientId, lastIndex, new AsyncCallback<HiMessage[]>() {
@Override
public void onFailure(Throwable caught) {
// TODO Auto-generated method stub
}
@Override
public void onSuccess(HiMessage[] result) {
if (result != null && result.length != 0) {
for (HiMessage message : result) {
if (message.getClientId() == clientId) {
contentPanel.add(new HiMessageUi("You:", message.getContent()));
} else {
contentPanel.add(new HiMessageUi("Stanger:", message.getContent()));
}
lastIndex++;
}
scrollPanel.scrollToBottom();
}
isUpdating = false;
}
});
}
}
}
private void update() {
if (clientId == -1) {
initClientId();
} else {
if (!isUpdating) {
isUpdating = true;
service.updateMessage(clientId, lastIndex, new AsyncCallback<HiMessage[]>() {
@Override
public void onFailure(Throwable caught) {
// TODO Auto-generated method stub
}
@Override
public void onSuccess(HiMessage[] result) {
if (result != null && result.length != 0) {
for (HiMessage message : result) {
if (message.getClientId() == clientId) {
contentPanel.add(new HiMessageUi("You:", message.getContent()));
} else {
contentPanel.add(new HiMessageUi("Stanger:", message.getContent()));
}
lastIndex++;
}
scrollPanel.scrollToBottom();
}
isUpdating = false;
}
});
}
}
}
呃,改后bug依然坚挺,悲剧地发现,这个bug不是这个原因造成的。而 是取信息的时候,相当无语地返回了所有的信息。。。改成这样就好了
@Override
public HiMessage[] updateMessage(int clientId, int lastIndex) {
ArrayList<HiMessage> messageList = clientMgr.getClient(clientId).getRoom().getMessageList();
if (lastIndex >= messageList.size()) {
return null;
}
HiMessage[] result = new HiMessage[messageList.size() - lastIndex];
messageList.subList(lastIndex, messageList.size()).toArray(result);
return result;
}
public HiMessage[] updateMessage(int clientId, int lastIndex) {
ArrayList<HiMessage> messageList = clientMgr.getClient(clientId).getRoom().getMessageList();
if (lastIndex >= messageList.size()) {
return null;
}
HiMessage[] result = new HiMessage[messageList.size() - lastIndex];
messageList.subList(lastIndex, messageList.size()).toArray(result);
return result;
}
而是取信息的时候,相当无语地返回了所有的信息。。。改成这样就好了
@Override
public HiMessage[] updateMessage(int clientId, int lastIndex) {
ArrayList<HiMessage> messageList = clientMgr.getClient(clientId).getRoom().getMessageList();
if (lastIndex >= messageList.size()) {
return null;
}
HiMessage[] result = new HiMessage[messageList.size() - lastIndex];
messageList.subList(lastIndex, messageList.size()).toArray(result);
return result;
}
public HiMessage[] updateMessage(int clientId, int lastIndex) {
ArrayList<HiMessage> messageList = clientMgr.getClient(clientId).getRoom().getMessageList();
if (lastIndex >= messageList.size()) {
return null;
}
HiMessage[] result = new HiMessage[messageList.size() - lastIndex];
messageList.subList(lastIndex, messageList.size()).toArray(result);
return result;
}
虽然如此,但是我认为之前的想法仍然是对的,异步调用不加锁是一种潜在的威胁,因此我还是保留了之前的修改。