アクティビティコンテキストとアプリケーションコンテキストの違い


233

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

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

そしてまた

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

getApplicationContext()両方のクラッシュを使用するProgressDialogToast、この質問につながります:

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


これは私が見つけたものですstackoverflow.com/questions/1561803/… ....
t0mm13b 2010年

14
これは、いくつかのことを明確にするのに役立ちます:コンテキスト、どのコンテキスト?
toobsco42 2013年

回答:


250

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

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

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

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


1
getApplicationContext興味深いことに、に変更するthisと「java.lang.reflect.InvocationTargetException」が発生しましたが、に変更すると、クラッシュせず期待どおりに機能しませんでした。他はしますか?この情報は、私が望む他の人の助けになるでしょう... :)迅速な回答に感謝します...
t0mm13b 2010年

2
何でも言えるようにするには、完全な例外スタックトレースを確認する必要があります。ただし、前述したように、コンテキストインスタンスには異なる情報があります。おそらく画面にダイアログまたはトーストを表示するには、Activityインスタンスのみが持つActivityに関する情報が必要です。
シェリルサイモン

74
十分な理由がない限り(つまり、ダイアログやトーストのために)アプリコンテキストを使用することをお勧めします。安全:)する最善のように、それは、さまざまな状況での活動のコンテキストを使用してメモリリークに実行するのは非常に簡単ですandroid-developers.blogspot.com/2009/01/...
通り

10
Dave Smithは、コンテキストの使用法を理解するための非常に優れたブログエントリを投稿しましたこちらを参照してください。コメントも必ず読んでください!
ChrLipp 2013

1
問題は、Dianna Hackbornでさえ、アクティビティコンテキストを使用することを推奨しているということです。stackoverflow.com/questions/5228160/…しかし、彼女自身はこれについて完全に確信していないようです。
JacksOnF1re 2015年

178

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

ここに画像の説明を入力してください

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

元記事はこちら



リソースの取得についてはどうですか?私はあなたがそれをあなたのテーブルに加える方が良いと思います。applciationコンテキストでリソースにアクセスできます。
Amir Ziarati、2017年

アプリケーションコンテキストからアクティビティを開始できます
Duy Phan

記事はまた、ここで見つけることができます:wundermanthompsonmobile.com/2013/06/context
静物

34

これは明らかにAPI設計の欠陥です。そもそも、Activity ContextとApplication Contextはまったく異なるオブジェクトなので、コンテキストが使用されるメソッドパラメータは、親クラスContextを使用する代わりに、ApplicationContextまたはActivity直接使用する必要があります。第二に、ドキュメントはどのコンテキストを使用するか明示的に指定しないでください。


25
完全に同意します。グーグルはこれにボールを落とした。それは完全な混乱です。
セーレンBoisen

@SørenBoisenandroid sdkは完全に混乱しています
CommonSenseCode '

彼らは混乱を認識しており、できる限り修正するのに苦労しています。
署名

15

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


3

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

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


2

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


1

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

ここで、@ CommonSenseCodeによって言及された「非標準のバックスタックの動作」の意味の実際的な例は、次のとおりです。

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

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

今あなたがいると仮定します のApp1と打ち上げMainActivity:App2の意思シェア(ACTION_SENDまたはACTION_SEND_MULTIPLE)と。次に、そこからApp2:SecondaryActivityを起動してみます(常にすべての標準の起動モードとインテントフラグを使用)。何が起こるか:

  • Android <10でアプリケーションコンテキストを使用してApp2:SecondaryActivityを起動すると、起動できませんすると、同じタスクですべてのアクティビティを。私はアンドロイド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をアクティビティコンテキストで起動すると、すべてがうまくいき、すべてのアクティビティを同じタスクで実行できるため、線形のバックスタックナビゲーションが実現します。

役立つ情報を追加したかと思います

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.