36

進行中の学習プロセス (今回はダイアログ ボックス) で、これが機能することを発見しました。

  AlertDialog.Builder builder = new AlertDialog.Builder(this);

以下は機能しませんが (実行時に WindowManager$BadTokenException で失敗します):

  AlertDialog.Builder builder = new AlertDialog.Builder(this.getApplicationContext());

AlertDialog.Builderのコンストラクターは、Activity ではなく Context をパラメーターとして受け入れるように定義されているため、理由がわかりません。

public AlertDialog.Builder (コンテキスト コンテキスト)

このビルダーのコンテキストとそれが作成する AlertDialog を使用するコンストラクター。

私は何が欠けていますか?

4

2 に答える 2

26

アクティビティはコンテキストを継承します。AlertDialog.Builder は Context 引数を指定します。これは、Activity、ListActivity、Service など、Context のサブクラスである任意のクラスで使用できるためです。 Joshua Bloch の素晴らしい「Effective Java」の項目 I8 (インターフェイスと抽象クラスについて) を読むことによって。

getApplicationContext() は、アプリケーションのコンテキストを返します。これは、アクティビティのコンテキストとほとんど同じです。「ほとんど」は、あなたを失望させているものです。詳細は不明ですが、これは広く発生する問題であり、典型的な答えは、アラートを画面に書き込むコンテキストを使用することです。これはgetApplicationContext() によって返されるものではないことに注意してください。

あなたが私のような人なら、「しかし、私は Activity から継承しないクラスで作業しています。それが、そもそもこれに getApplicationContext() を使用したい理由です。当然です!」と言うかもしれません。私は実際にはそれほど無礼に話していません ;p .. 要点は、私もここにいたことがあるということでした。私はそれを次のように修正しました:1)「アクティビティ間で共有したいので、UI AlertDialogコードを非アクティビティクラスに持っていますか..またはListActivities、Services、...でさえ共有したいですか?」。そうでない場合は、うーん... UI (したがってコンテキスト) にアクセスできることを保証できないコードに AlertDialog UI 呼び出しが本当にありますか? その場合は、設計を再検討してください。

このクラスをアクティビティ間で共有したいと仮定すると、答えは明らかです。おそらくそれぞれ独自のコンテキストを持つさまざまな呼び出し元がクラスを使用できるようにする必要があります。したがって、呼び出し元はそのコンテキストを引数としてクラスに渡す必要があります。

myClass(Context theContext, ...) { ... }

次に、各アクティビティ、サービスなどは次のように呼び出します。

myClass(this, ...);

見覚えがあります?

気をつけて!コードを共有している場合は、さまざまな呼び出しが共有コードに並行して入る可能性を考慮する必要があります。それはここでの私たちの範囲を超えています...

楽しむ :)

于 2011-03-29T00:29:24.633 に答える