getContext()
、getApplicationContext()
、getBaseContext()
、および "this
"の違いは何ですか?
これは簡単な質問ですが、基本的な違いはわかりません。可能であればいくつかの簡単な例を挙げてください。
View.getContext()
:ビューが現在実行されているコンテキストを返します。通常は現在アクティブなActivityです。
Activity.getApplicationContext()
:アプリケーション全体のコンテキスト(すべてのアクティビティが内部で実行されているプロセス)を返します。現在のActivityだけでなく、アプリケーション全体のライフサイクルに関連したコンテキストが必要な場合は、現在のActivityコンテキストの代わりにこれを使用してください。
ContextWrapper.getBaseContext()
:他のコンテキスト内からコンテキストへのアクセスが必要な場合は、ContextWrapperを使います。そのContextWrapperの内側から参照されるContextはgetBaseContext()を通してアクセスされます。
ほとんどの回答はすでにgetContext()
とgetApplicationContext()
をカバーしていますが、 getBaseContext() はほとんど説明されていません。
メソッドgetBaseContext()
は、あなたがContextWrapper
name__を持っている場合にのみ関係します。 Androidは、既存のContextWrapper
name__を中心に作成されたContext
name__クラスを提供します。
ContextWrapper wrapper = new ContextWrapper(context);
ContextWrapper
name__を使用する利点は、「元のコンテキストを変更せずに動作を変更できる」ということです。たとえば、myActivity
name__というアクティビティがある場合、View
name__とは異なるテーマでmyActivity
name__を作成できます。
ContextWrapper customTheme = new ContextWrapper(myActivity) {
@Override
public Resources.Theme getTheme() {
return someTheme;
}
}
View myView = new MyView(customTheme);
ContextWrapper
name__は、リソースにアクセスするためのコード(openFileInput()
、getString()
など)を含むContext
name__によって提供されるほとんどの関数をオーバーライドし、他のコンポーネントと対話し(例えばsendBroadcast()
、registerReceiver()
)、許可を要求し(例えばcheckCallingOrSelfPermission()
)、ファイルシステムの場所(例えば) getFilesDir()
)。 ContextWrapper
name__は、デバイス/バージョン固有の問題を回避したり、ビューなどのコンテキストを必要とするコンポーネントに個別のカスタマイズを適用したりするのに非常に便利です。
メソッド getBaseContext() を使用すると、ContextWrapper
name__がラップアラウンドする「ベース」コンテキストにアクセスできます。必要に応じて、「ベース」コンテキストにアクセスする必要があります。たとえば、それがService
name__、Activity
name__、またはApplication
name__であるかどうかを確認します。
public class CustomToast {
public void makeText(Context context, int resId, int duration) {
while (context instanceof ContextWrapper) {
context = context.baseContext();
}
if (context instanceof Service)) {
throw new RuntimeException("Cannot call this from a service");
}
...
}
}
あるいは、ラップされていないバージョンのメソッドを呼び出す必要がある場合は、次のようにします。
class MyCustomWrapper extends ContextWrapper {
@Override
public Drawable getWallpaper() {
if (BuildInfo.DEBUG) {
return mDebugBackground;
} else {
return getBaseContext().getWallpaper();
}
}
}
getApplicationContext() - アプリケーションで実行されているすべてのアクティビティのコンテキストを返します。
getBaseContext() - アプリケーション内の別のコンテキストからContextにアクセスする場合は、アクセスできます。
getContext() - コンテキストビューのみを現在実行中のアクティビティとして返します。
Context
は、新しく作成されたコンポーネントにActvity
またはApplication
に関する情報を提供します。
関連するContext
は新しく作成されたコンポーネントに提供されるべきです(アプリケーションコンテキストかアクティビティコンテキストかにかかわらず)
Activity
はContext
のサブクラスなので、そのアクティビティのコンテキストを取得するためにthis
を使うことができます。
「コンテキストとは何か」という質問は、Androidの世界で最も難しい質問の1つです。
コンテキストは、システムリソースへのアクセス、アプリケーションの静的アセットの取得、権限の確認、UI操作の実行などを行うメソッドを定義します。本質的に、Context
は生産におけるゴッドオブジェクトアンチパターンの例です。
どの種類のContext
を使うべきかということになると、それは非常に複雑になります。なぜなら、Context
サブクラスの階層ツリーは、神オブジェクトであることを除いて、残念ながらLiskov Substitution Principleに違反するからです。
このブログ記事 はさまざまな状況でのContext
クラスの適用性を要約しようとしています。
完全を期すためにその記事のメインテーブルをコピーしてみましょう。
+----------------------------+-------------+----------+---------+-----------------+-------------------+ | | Application | Activity | Service | ContentProvider | BroadcastReceiver | +----------------------------+-------------+----------+---------+-----------------+-------------------+ | Show a Dialog | NO | YES | NO | NO | NO | | Start an Activity | NO¹ | YES | NO¹ | NO¹ | NO¹ | | Layout Inflation | NO² | YES | NO² | NO² | NO² | | Start a Service | YES | YES | YES | YES | YES | | Bind to a Service | YES | YES | YES | YES | NO | | Send a Broadcast | YES | YES | YES | YES | YES | | Register BroadcastReceiver | YES | YES | YES | YES | NO³ | | Load Resource Values | YES | YES | YES | YES | YES | +----------------------------+-------------+----------+---------+-----------------+-------------------+
- アプリケーションはここからアクティビティを開始できますが、新しいタスクを作成する必要があります。これは特定のユースケースに合うかもしれませんが、あなたのアプリケーションの中で非標準のバックスタックの振る舞いを作り出すことができます、そして、一般的にはお勧めできないか、良い習慣と考えられません。
- これは有効ですが、インフレーションはアプリケーションで定義されているものではなく、実行しているシステムのデフォルトテーマで行われます。
- Android 4.2以降で、受信側がnullの場合、許可されます。これは、スティッキーブロードキャストの現在の値を取得するために使用されます。
getApplicationContext()
これはアプリケーションレベルで使用され、すべてのアクティビティを指します。
getContext()およびgetBaseContext()
たぶん同じである。これらは生きている現在の活動だけに依存している。
この
常に現在のクラスオブジェクトを参照します。