getContext()、getApplicationContext()、getBaseContext()と“ this”の違い


565

どのような違いがあるgetContext()getApplicationContext()getBaseContext()"、およびthis「?

これは簡単な質問ですが、両者の基本的な違いを理解できません。可能であれば簡単な例を挙げてください。


1
:最初の答えに優れた過去記事があり stackoverflow.com/questions/1026973/...
ky1enamic

回答:


528
  • View.getContext():ビューが現在実行されているコンテキストを返します。通常は、現在アクティブなアクティビティです。

  • Activity.getApplicationContext():アプリケーション全体のコンテキスト(すべてのアクティビティが内部で実行されているプロセス)を返します。現在のアクティビティだけでなく、アプリケーション全体のライフサイクルに関連付けられたコンテキストが必要な場合は、現在のアクティビティコンテキストの代わりにこれを使用します。

  • ContextWrapper.getBaseContext():別のコンテキスト内からコンテキストにアクセスする必要がある場合は、ContextWrapperを使用します。そのContextWrapperの内部から参照されるコンテキストには、getBaseContext()を介してアクセスします。


59
そして、「これ」はどうですか?
CooL i3oY 2012

16
+ CooL i3oYはgetContextと同じ
Mikey

13
実際には、コンテキストの適切な定義は何ですか?
Ravi

11
「this」とgetContext()はどちらも同じです
KCRaju 2013

43
thisgetContext()常に同じではありません。たとえば、Activityクラスでは、継承元ですがメソッドはクラスにないthisため、使用できます。@mikedroid @KCRajuActivityContextgetContext()Activity
nandan

92

ほとんどの回答はすでにカバーgetContext()してgetApplicationContext()いますが、getBaseContext()についてはほとんど説明されていません。

このメソッドgetBaseContext()は、ContextWrapper。AndroidはContextWrapper、既存のものContextを使用して作成されたクラスを提供します。

ContextWrapper wrapper = new ContextWrapper(context);

aを使用する利点は、ContextWrapper「元のコンテキストを変更せずに動作を変更」できることです。たとえば、というアクティビティがある場合myActivityViewとは異なるテーマでを作成できますmyActivity

ContextWrapper customTheme = new ContextWrapper(myActivity) {
  @Override
  public Resources.Theme getTheme() { 
    return someTheme;
  }
}
View myView = new MyView(customTheme);

ContextWrapperContextリソースへのアクセス(例:)openFileInput()getString()他のコンポーネントとのやり取り(例:)sendBroadcast()registerReceiver()アクセス許可の要求(例checkCallingOrSelfPermission():)、およびファイルシステムの場所の解決(例:)を行うコードを含めることで提供されるほとんどの機能をオーバーライドできるため、非常に強力getFilesDir()です。ContextWrapperデバイス/バージョン固有の問題を回避したり、コンテキストを必要とするビューなどのコンポーネントに1回限りのカスタマイズを適用したりするのに非常に便利です。

メソッドgetBaseContext()を使用して、ContextWrapperラップする「ベース」コンテキストにアクセスできます。あなたは、例えば、それはだかどうかを確認する必要がある場合は、「ベース」コンテキストにアクセスする必要があるかもしれませんServiceActivityまたはApplication

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();
    }
  }
}

17
これは、受け入れられた答えの後に最も重要な答えです。
0leg 2017年

4
の存在はContextWrapper、Androidフレームワークの開発者がこれまでに行った最悪の決定の1つだと思います。神オブジェクトのファミリー全体を作成したことに気づいたとき、正しいことを行ってコードを単一の責任にリファクタリングする代わりに、継承ツリーを深くすることでコンテキストの動作を変更できる醜いハックを追加しました。その醜い状態で悪いソフトウェア工学。私たちのためとして、開発者は、私見誰も使うべきではありませんgetBaseContext()ContextWrapper。もしそうなら-それは巨大な「コードのにおい」です。
Vasiliy 2017年

完全なCustomToastコードを見たいのですが。THANKS :)))
アルストン

39

getApplicationContext() -アプリケーションで実行されているすべてのアクティビティのコンテキストを返します。

getBaseContext() -アプリケーション内の別のコンテキストからContextにアクセスする場合にアクセスできます。

getContext() -現在実行中のアクティビティのみのコンテキストビューを返します。


1
Plsは、AとBの文字を、コンテキストのあるコンテキストの定義に組み込みます。どのコンテキストにアクセスするかは、どの回答でも明確ではありません。
2016

29

「コンテキストとは」という質問は、Androidの世界で最も難しい質問の1つです。

コンテキストは、システムリソースへのアクセス、アプリケーションの静的アセットの取得、権限の確認、UI操作の実行などを行うメソッドを定義します。本質的にContextは、生産における神のオブジェクトのアンチパターンの例です。

どの種類Contextを使用すればよいかというと、Contextサブクラスの階層ツリーが神のオブジェクトであることを除いて、リスコフの置換原理に容赦なく違反するため、非常に複雑になります。

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

スクリーンショット


あなたがリンクした素晴らしいブログ投稿!
lejonl 2017年

28

Context についての情報を提供します ActvityまたはApplication新しく作成されたコンポーネントます。

関連 Context新しく作成されたコンポーネント(アプリケーションコンテキストかアクティビティコンテキストかにを提供必要があります

ActivityはのサブクラスなのでContext、を使用thisしてそのアクティビティのコンテキストを取得できます


baseContextについての説明はどこにありますか?
IgorGanapolsky

1

これから ドキュメント

私はあなたが使うべきであると理解しました:

コンテキストアクティビティの代わりにコンテキストアプリケーションを使用してみてください


0

getApplicationContext()

これはアプリケーションレベルで使用され、すべてのアクティビティを参照します。

getContext()およびgetBaseContext()

おそらく同じです。これらは、現在行われている現在のアクティビティのみが参照されます。

この

常に現在のクラスオブジェクトを参照します。


0

A Contextは:

  • Androidシステムによって実装が提供される抽象クラス。
  • これにより、アプリケーション固有のリソースとクラスへのアクセスが可能になり、アクティビティの起動、インテントのブロードキャストと受信などのアプリケーションレベルの操作のアップコールが可能になります。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.