252

これは私を困惑させました、私はこれをAndroid 2.1-r8SDKで使用していました:

ProgressDialog.show(getApplicationContext(), ....);

そしてまた

Toast t = Toast.makeText(getApplicationContext(),....);

getApplicationContext()クラッシュProgressDialogと....の両方を使用Toastすると、この質問につながります。

「コンテキスト」という表現を共有しているにもかかわらず、アクティビティコンテキストとアプリケーションコンテキストの実際の違いは何ですか?

4

7 に答える 7

276

どちらもContextのインスタンスですが、アプリケーション インスタンスはアプリケーションのライフサイクルに関連付けられていますが、アクティビティ インスタンスはアクティビティのライフサイクルに関連付けられています。したがって、アプリケーション環境に関するさまざまな情報にアクセスできます。

getApplicationContextのドキュメントを読むと、ライフサイクルが現在のコンテキストとは別のコンテキストが必要な場合にのみ、これを使用する必要があることがわかります。これは、どちらの例にも当てはまりません。

Activity コンテキストには、おそらく、これらの呼び出しを完了するために必要な現在のアクティビティに関する情報が含まれています。正確なエラー メッセージを表示すると、必要なものを正確に指摘できる場合があります。

ただし、一般的には、正当な理由がない限り、アクティビティ コンテキストを使用してください。

于 2010-11-08T22:33:52.667 に答える
210

この表は、さまざまなタイプのコンテキストをいつ使用するかを決定するのに非常に役立ちます。

ここに画像の説明を入力

  1. アプリケーションはここからアクティビティを開始できますが、新しいタスクを作成する必要があります。これは特定のユース ケースに適合する可能性がありますが、アプリケーションで非標準のバック スタック動作を作成する可能性があるため、一般的に推奨されていないか、良い方法と見なされていません。
  2. これは合法ですが、インフレーションは、アプリケーションで定義されているものではなく、実行しているシステムのデフォルトのテーマで行われます。
  3. Android 4.2 以降でスティッキー ブロードキャストの現在の値を取得するために使用されるレシーバーが null の場合に許可されます。

元の記事はこちら.

于 2016-02-03T23:17:36.177 に答える
37

これは明らかに API 設計の欠陥です。そもそもActivity ContextとApplication contextは全く別のオブジェクトなので、contextを使うメソッドのパラメータは親クラスのContextではなくApplicationContextorActivityを直接使うべきです。次に、ドキュメントでは、使用するコンテキストを明示的に指定する必要があります。

于 2014-06-30T09:52:52.397 に答える
17

私が思う理由は、アクティビティが破棄された後にダイアログを残すことができないProgressDialogため、アクティビティにアタッチされているため、アクティビティとともに破棄ProgressDialogされる (ActivityContext) を渡す必要がthisあるのに対し、ApplicationContext はアクティビティが取得された後も残るためです。破壊されました。

于 2014-07-25T10:59:18.193 に答える
3

それ自体がグローバル スコープを持つ Context に関連付けられたものが必要な場合は、getApplicationContext() を使用します。

Activity を使用する場合、新しい Activity インスタンスには、古い Activity への暗黙的な参照を持つ参照があり、古い Activity はガベージ コレクションできません。

于 2016-03-04T05:59:44.477 に答える
3

すべてに表示する画面 (ボタン、ダイアログ、レイアウト...) が必要な場合は、コンテキスト アクティビティを使用する必要があり、すべてに表示または処理する画面は必要ありません (トースト、サービス電話、連絡先...)。アプリケーションコンテキストを使用できます

于 2015-05-04T06:03:44.893 に答える
3

アプリをホーム画面から直接起動した場合と、共有インテントを介して別のアプリから起動した場合の 2 つのコンテキストの違いを確認できます。

@CommonSenseCode で言及されている「非標準のバックスタック動作」の実際の例を以下に示します。

互いに通信する 2 つのアプリApp1App2があるとします。

ランチャーからApp2:MainActivityを起動します。次に MainActivity からApp2:SecondaryActivityを起動します。そこでは、アクティビティ コンテキストまたはアプリケーション コンテキストのいずれかを使用して、両方のアクティビティが同じタスク内にあり、これで問題ありません (標準の起動モードとインテント フラグをすべて使用する場合)。バック プレスで MainActivity に戻ることができ、最近のアプリではタスクが 1 つしかありません。

App1にいて、共有インテント (ACTION_SEND または ACTION_SEND_MULTIPLE) でApp2:MainActivityを起動するとします。次に、そこからApp2:SecondaryActivityの起動を試みます(常にすべての標準起動モードとインテント フラグを使用します)。何が起こるか:

  • Android < 10 でアプリケーション コンテキストを使用して App2:SecondaryActivity を起動すると、同じタスクですべてのアクティビティを起動することはできません。Android 7 および 8 で試してみましたが、SecondaryActivity は常に新しいタスクで起動されます (App2:SecondaryActivity が App2 アプリケーション コンテキストで起動されるためだと思いますが、App1 から来ており、App2 アプリケーションを直接起動しなかったためです)。たぶん内部で Android がそれを認識し、FLAG_ACTIVITY_NEW_TASK を使用します)。私のアプリケーションが悪かったため、これはニーズに応じて良い場合も悪い場合もあります。 Android 10 でアプリがクラッシュし、 「Activity コンテキストの外部から startActivity() を呼び出すには FLAG_ACTIVITY_NEW_TASK フラグが必要です。これは本当に必要ですか?」というメッセージが表示されます。.


    したがって、Android 10 で動作させるには、FALG_ACTIVITY_NEW_TASK を使用する必要があり、同じタスクですべてのアクティビティを実行することはできません。
    ご覧のとおり、Android のバージョンによって動作が異なります。

  • アクティビティ コンテキストを使用して App2:SecondaryActivity を起動すると、すべてがうまくいき、同じタスクですべてのアクティビティを実行できるため、バックスタック ナビゲーションが線形になります。

有益な情報を追加できたと思います

于 2019-11-14T12:37:51.347 に答える