質問

アクティビティと場所を使用してGWT MVPアプリケーションがあります。これは、マウロ・バルタペルのサンプルに触発されています( このスレッド)、明らかにいくつかに基づいています トーマス・ブロイヤー仕事。

問題は次のとおりです。LoginActivityがRPC呼び出しを行います。これは、ログインを成功させるためにユーザーを返します。このユーザーには役割があります(たとえば、管理者、通常のユーザー、ゲスト)。 NavigatorViewを含むいくつかのビューやアクティビティは、彼らが示すことやすることのこの役割に依存しています。このユーザーインスタンスを他のアクティビティに届けるにはどうすればよいですか?

クライアントファクトリーはありません。インジェクション(GIN)は、私のアクティビティ/プレゼンターを提供するアクティビティプロバイダーのビューをインスタンス化するために使用され、ActivityProvidersが私のActivityMapperに注入されます。したがって、これはジンの質問に減るかもしれません:ユーザーの参照が必要な場所を取得するにはどうすればよいですか?これはに似ているようです これはとても質問です MVPのグローバル参照について。

私をジンの初心者と考えてください。これは私の最初の試みです。これを実現するための「ジンのやり方」があると思いますが、これを行うための最良の方法を知るのに十分なことはありません(ジンをまったく使用する必要がある場合)。

どうもありがとう。

編集1: 私の最善の努力を検索しているにもかかわらず、同様の質問を求めて、私はちょうど見つけました この質問 これは私のものとほぼ同じです(「関連」リンクを検索よりも優れているためのアルゴリズムはありますか?)。デビッドのジンの答えは正しい軌道に乗っていると思います。

EventBusソリューションが可能だとは思いません。私はフォローしています Googleガイドライン すべての場所でのインスタンス化アクティビティが変更されるため、単一のイベント自体では十分ではありません。

役に立ちましたか?

解決

最近のプロジェクトでも同様の要件がありました。

login(またはlogout)RPCから返信を取得すると、EventBusにカスタムAuthenticationEventを送信します。これに興味のあるすべてのアクティビティは、このイベントに耳を傾けます。 AuthenticationEventには、ユーザーがログアウトした場合にnullであるAppuserオブジェクトへの参照があります。 Appuserには、必要なすべてのデータ(特権、グループなど)が含まれているため、アクティビティがそれを検査して行動することができます。

グローバル参照について:必要なデータを提供する静的メソッドを備えたクラスを使用できます。このクラスは、必要なインスタンスへのシングルトンの参照を内部的に保持しています。私の例では、静的メソッドapputils.getCurrentuser()があります。内部的には、Aupuserへの参照を保持し、このフィールドを設定/リセットするためにAuthenticationEventにも耳を傾けます。

サイドノート:アクセス制限を実施するためにクライアント側に頼らないでください - RPCサーブレットをパブリックとプライベートの2つのグループに分離する必要があります。パブリックには誰でもアクセスできます(これは基本的にログイン/ログアウトRPCおよびその他の公開情報RPCです)が、プライベートRPCではユーザーの認証を必要とします。アクセス制限は、パス/サーブレットごとに設定できます。 http://code.google.com/appengine/docs/java/config/webxml.html#security_and_authentication

アップデート:

  1. あなたが述べたように、このセットアップでは静的な方法を持つクラスは、置き換えられず、これがテストを防ぐため、このセットアップではお勧めしません(これはGINを使用するポイントです)。

  2. 解決策は、グローバルを保持しているユーティリティクラスをグローバルを必要とするアクティビティに注入することです。 Apputilsは、アプリ全体に1つのインスタンスで十分であるため、ジン構成でシングルトンと宣言する必要があります。

  3. 使用する Provider 依存関係の初期化を遅らせる場合は、単なる質問です(Apputilは依存関係です)。 Apputilsはアプリ全体のシングルトンであるため、怠zyな初期化することは意味がありません。

  4. 画面に複数のアクティビティが表示される状況がある場合があります(私の場合、メノバーとインフォバーでした)。この場合、ユーザーがログインすると、変更を通知する方法が必要です。 EventBusを使用します。

他のヒント

Guiceでサーバー側で使用しているもので、クライアント側でも同様に機能することは、カスタムプロバイダーにバインドすることです。ただし、あなたの場合、プロバイダーをシングルトンにし、RPCコールバックから値を押し込む必要があります(コンテキストからそれを引くのではなく)。最初に特定のプロバイダーが必要です。

@Singleton
public class CurrentUserProvider implements Provider<User> {
  private User currentUser;

  public User get() { return currentUser; }
  public void setCurrentValue(User currentUser) {
    this.currentUser = currentUser;
  }
}

あなたはバインドします User プロバイダーに: bind(User.class).toProvider(CurrentUserProvider.class)RPCコールバックでは、aを注入します CurrentUserProvider だからあなたはできる setCurrentValue しかし、どこでもあなたは注入するでしょう Provider<User> 保つ CurrentUserProvider 実装の詳細として。非常に短命のオブジェクトの場合、あなたは直接注入することができます User aではなく値 Provider<User>.

値の変更をオブジェクトに通知する必要がある場合は、グローバルイベントバスでイベントを発送できます。

あるいは、コンクリートをいつでも使用できます CurrentUserProvider タイプ(実装する必要はありません Provider もう)そして、おそらくそれを作ります HasValueChangeHandlers そのため、イベントバスではなく、リスナーを登録できます(ただし、アクティビティで自分の後にクリーンアップする必要があります」 onStoponCancel メモリリークを避けるために、イベントバスにハンドラーを登録すると自動的に世話をします onStart).

(あなたが私に尋ねるなら、私は可能な限りアプリ内から認証を受けに行きたいです)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top