バックグラウンド ストーリー:
標準の MVP デザイン パターンを使用し、RPC を使用してカスタム データ処理サーブレットからデータを取得する GWT アプリケーションを開発しています (舞台裏で多くのことを行います)。とにかく、私の目標は、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 の 2 つのアクティビティができました ( GWT MVP コードから取得)
。ハンドラーが呼び出されると、メッセージも出力されます。とにかく、これは私がログから得た出力です:(正しくありません)
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 Problem Project Exampleで見つけることができます。
eventBus.fireEventFromSource(...)
編集:実際の GWT アプリケーションでは、イベント用に複数の登録済みハンドラーがあるため、 using はデバッグ目的でのみ使用されていることに
注意してください。では、EventBus を適切に使用するにはどうすればよいでしょうか。