История вопроса:
Я занимаюсь разработкой приложения GWT, используя стандартный шаблон проектирования MVP, а также использую RPC для получения данных из моего собственного сервлета обработки данных (многое делает за кулисами). В любом случае, моя цель - создать очень простой пользовательский механизм кэширования, который хранит данные, возвращаемые из обратного вызова RPC, в статическом кеше POJO. (Обратный вызов также отправляет пользовательское событие, используя SimpleEventBus, всем зарегистрированным обработчикам.) Затем, когда я снова запрашиваю данные, я проверю кэш перед повторным вызовом сервера RPC. (А также отправьте пользовательское событие, используя EventBus).
Проблема:
Когда я отправляю событие из обратного вызова RPC, все работает нормально. Проблема в том, что когда я отправляю кэшированный объект, я отправляю событие за пределами обратного вызова RPC. По какой-то причине это событие не попадает в мой зарегистрированный обработчик. Вот некоторый код:
public void callServer(final Object source)
{
if(cachedResponse != null)
{
System.err.println("Getting Response from Cache for: "+ source.getClass().getName());
//Does this actually fire the event?
eventBus.fireEventFromSource(new ResponseEvent(cachedResponse),source);
}
else
{
System.err.println("Getting Response from Server for: "+ source.getClass().getName());
service.callServer(new AsyncCallback<String>(){
@Override
public void onFailure(Throwable caught) {
System.err.println("RPC Call Failed.");
}
@Override
public void onSuccess(String result) {
cachedResponse = result;
eventBus.fireEventFromSource(new ResponseEvent(cachedResponse),source);
}
});
}
}
Теперь у меня есть два вида деятельности: HelloActivity и GoodbyeActivity (взяты из: GWT MVP code )
Они также распечатывают сообщения при вызове обработчика. Во всяком случае, это вывод, который я получаю из журналов: (Не правильно)
Getting Response from Cache for: com.hellomvp.client.activity.HelloActivity
Response in GoodbyeActivity from: com.hellomvp.client.activity.HelloActivity
Getting Response from Cache for: com.hellomvp.client.activity.GoodbyeActivity
Response in HelloActivity from: com.hellomvp.client.activity.GoodbyeActivity
То, что я ожидаю получить, это:
Getting Response from Cache for: com.hellomvp.client.activity.HelloActivity
Response in HelloActivity from: com.hellomvp.client.activity.HelloActivity
Getting Response from Cache for: com.hellomvp.client.activity.GoodbyeActivity
Response in GoodbyeActivity from: com.hellomvp.client.activity.GoodbyeActivity
И я получу этот ожидаемый результат, если я изменю приведенный выше код на следующий: (Это весь файл на этот раз ...)
package com.hellomvp.client;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.hellomvp.events.ResponseEvent;
public class RequestManager {
private EventBus eventBus;
private String cachedResponse;
private HelloServiceAsync service = GWT.create(HelloService.class);
public RequestManager(EventBus eventBus)
{
this.eventBus = eventBus;
}
public void callServer(final Object source)
{
if(cachedResponse != null)
{
System.err.println("Getting Response from Cache for: "+ source.getClass().getName());
service.doNothing(new AsyncCallback<Void>(){
@Override
public void onFailure(Throwable caught) {
System.err.println("RPC Call Failed.");
}
@Override
public void onSuccess(Void result) {
eventBus.fireEventFromSource(new ResponseEvent(cachedResponse),source);
}
});
}
else
{
System.err.println("Getting Response from Server for: "+ source.getClass().getName());
service.callServer(new AsyncCallback<String>(){
@Override
public void onFailure(Throwable caught) {
System.err.println("RPC Call Failed.");
}
@Override
public void onSuccess(String result) {
cachedResponse = result;
eventBus.fireEventFromSource(new ResponseEvent(cachedResponse),source);
}
});
}
}
}
Итак, обратите внимание, единственное изменение состоит в том, что я создал новый вызов RPC, который ничего не делает, и отправил событие в своем обратном вызове с кэшированными данными вместо этого, и это заставит приложение работать должным образом ,
Итак, вопрос:
Что я делаю неправильно? Я не понимаю, почему 'eventBus.fireEvent (...)' Должен быть в Обратном вызове RPC, чтобы работать должным образом. Я думаю, что это проблема с многопоточностью, но я тщетно искал в Google все, что могло бы помочь.
У меня есть целый проект Eclipse, который демонстрирует эту проблему, которую я имею, ее можно найти по адресу: Пример проекта проблемы Eclipse
Изменить: Обратите внимание, что использование eventBus.fireEventFromSource(...)
используется только для целей отладки, поскольку в моем реальном приложении GWT у меня есть несколько зарегистрированных обработчиков для событий. Итак, как правильно использовать EventBus ?