2

バックグラウンド ストーリー:
標準の 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(...)編集:実際の G​​WT アプリケーションでは、イベント用に複数の登録済みハンドラーがあるため、 using はデバッグ目的でのみ使用されていることに 注意してください。では、EventBus を適切に使用するにはどうすればよいでしょうか。

4

1 に答える 1

1

あなたの問題を正しく理解していれば、呼び出しがオブジェクトSimpleEventBus#fireEventFromSourceにのみルーティングされることを期待していsourceます。これは当てはまりません。イベント バスは常に、登録されているすべてのハンドラに対してイベントを発生させます。一般に、 を使用する目的はEventBus、イベントのソースをそのハンドラーから分離するsourceことです。イベント実行の に基づく機能は、この目的に反します。

意図した以外の方法で概念AsyncCallbackを使用しようとするのではなく、キャッシング RPC クライアントに渡したい動作を取得します。これには、RPC 呼び出しが失敗したときに問題EventBusを警告するという追加の利点があります。Activity

public class RequestManager {
  private String cachedResponse = null;
  private HelloServiceAsync service = GWT.create(HelloService.class);

  public void callServer(final AsyncCallback<String> callback) {
    if (cachedResponse != null) {
      callback.onSuccess(cachedResponse);
    } else {
      service.callServer(new AsyncCallback<String>(){
        @Override
        public void onFailure(Throwable caught) {
          callback.onFailure(caught);
        }

        @Override
        public void onSuccess(String result) {
          cachedResponse = result;
          callback.onSuccess(cachedResponse);
        }
      });
    }
  }
}

そしてでActivity

clientFactory.getRequestManager().callServer(new AsyncCallback<String>() {
  @Override
  public void onFailure(Throwable caught) {
    // Handle failure.
  }

  @Override
  public void onSuccess(String result) {
    helloView.showResponse(result);
  }
});
于 2011-06-08T23:26:02.773 に答える