概要
何となくで使用していたContextについて学習をしました。
そのため、本ページにて学習した内容についてまとめます。
この記事を見て理解できること
この記事を見て理解できること
- AndroidのContextで出来ること
- contextの種類
- Fragmentで使用する際のcontextの取得方法
AndroidのContextで出来ること
AndroidにおけるContextの内容を展開
そもそもContextってどういう意味?
一般的な意味合いとAndroidにおけるContextの意味合いは以下になります。
- 一般的な意味合い:前後関係、文脈、脈絡、背景、状況、環境
- Androidにおける意味合い:同じコード記述やプログラム上の要素が、その置かれているプログラム内での位置や、実行される際の内部状態などによって異なる振る舞いをしたり、異なる制約を受けたりすること
AndroidのContextで出来ること(詳細)
AndroidのContextでできる内容は多岐に渡ります。
下記はできることの例です。
- リソースのアクセス: レイアウトファイルや文字列リソースなど、アプリケーションのリソースにアクセスできる
- システムサービスの取得:システムサービス(例えば、通知マネージャーやカメラなど)にアクセスできる
- アプリケーションの起動:Intentを介して新しいアクティビティの開始や、アプリケーションの起動ができる
画像でも分かる通り、Contextはアプリ内外の情報や機能をアクセスするための架け橋となっています。
※Androidシステムで使用できる機能については、下記ページに全て記載されてます。
Contextの種類
そもそもContextは抽象クラスになっています。
また、継承しているクラスは多く存在しているが、特に重要なものが以下2点になる。
→この二つを使用する場面が多い。
- ActiityのContext
- ApplicationのContext
Contextの継承について
ActivityのContextとApplicationのContextの継承については、下記画像にある通り、最終的に継承元が同じになります。
そのため、取得できる内容は同じになります。
Application ActivityのContextの違いについて
上記記載通り、取得できる内容に違いはないです。
そのため、どちらを使用するべきか悩むかと思います。(実際に最初にContextを使用した時は、どちらを使えばいいか悩んだ。)
どちらを使用するかについては、それぞれ依存内容が違うため、使用用途によって使い分ける必要があります!!
ActivityのContext
- 依存:Activityのライフサイクルに依存
- 使用用途:Activityのライフサイクル内での短期的な処理
ApplicationのContext
- 依存:アプリのライフサイクルに依存
- 使用用途:Worker等のバックグラウンド処理で使用
上記二つの依存関係を理解して使用することが重要です。
メモリリークについて
Contextについては、使用方法を間違えるとメモリリークを引き起こすことがあります。
例:リスナーやコールバックの解除が行えていない
public class MyActivity extends Activity {
private MyReceiver receiver = new MyReceiver();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
IntentFilter filter = new IntentFilter("SOME_ACTION");
registerReceiver(receiver, filter);
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver); // 解除を行わないとメモリリークの原因になる。
}
}
Fragmentで使用する際のcontextの取得方法
FragmentでActivityのcontetを使用する方法は、下記4パターンあります。
- getContext()
- getActivity()
- requireContext()
- requireActivity()
また、require〇〇とget〇〇の違いはContextが存在しない場合のreturn値が異なります。
- require〇〇の場合:例外を吐く
- get〇〇の場合:nullを返す
〇〇Activityと〇〇Contextの違いは、取得できるContextの種類が違います。
- 〇〇Activityの場合:ActivityのContextを取得できる
- 〇〇Contextの場合:ApplicationのContextを取得できる
上記の事からまとめると以下になります。
Contextがない場合の返り値 | 取得できるContextの種類 | |
---|---|---|
getContext | null | Application Context |
getActivity | null | Activity Context |
requireContext | 例外 | Application Context |
requireActivity | 例外 | Activity Context |
requireActivity()の使い方注意点
ActivityのContextはonAttach
の後から使用できてonDetach
のタイミングで使用できなくなります。
そのため、バックグラウンド処理した内容を受け取りそれを基に処理などをする時に、require〇〇を読んでしまうと、既にDetach()されている可能性もあります。(通信が終わる前にFragmentが破棄されている等)
そのため、使用には注意が必要になります。
これを加味するとget〇〇を使ってnullセーフな使い方をするのが無難です。