勉強:thisとgetContextの違いについて
プログラムで
thisを使っているところもあったり
getApplicationContextも使っているところもあったり
違いはなんなのかなーーー?
と思ったので、確認。
以下引用
●Contextのライフサイクル
ApplicationContextはアプリケーションのライフサイクルと連動し、ActivityContextは
アクティビティのライフサイクルと連動しています。
つまり、2つはどちらもContextインスタンスではありますが、中身は全く異なるものに
なります。
ContextのライフサイクルについてはDeveloperページのgetApplicationContextが参考に
なります。
以下要約です。BroadcastReceiverを登録するregistReceiverを使用するケースにおいて...
・ActivityContextを使った場合
レシーバはActivityと関連付けて登録されます。システムはActivityが破棄される
前に登録したBroadcastReceiverがunregistReceiverされることを期待します。
もしunregistReceiverされなかった場合は、フレームワークがこれをクリーンナップし、
エラーログを出力します。
・ApplicationContextを使った場合
レシーバはApplicationと関連付けて登録されグローバルな状態となる。
そのためフレームワークがこれをクリーンアップすることがなく、unregistReceiverを
忘れると容易にリークしてしまいます。参考:http://developer.android.com/reference/android/content/Context.html#getApplicationContext()
Contextを渡す対象のAPIは、ActivityかApplicationどちらが良いのかについては、
ライフサイクルを意識することも重要であることが上記からわかります。
●Context保持によるメモリリーク問題
Contextに関するメジャーな問題としてメモリリークがあります。
前述からもわかるようにContextへの参照はActivityへの参照でもある可能性があります。
下記のようにActivityContextを長期間保持するようなコードは簡単にメモリリークを引
き起こす可能性があります。private static Context mContext; // ... mContext = activityInstance;ActivityContextはActivityのライフサイクルと連動していることを思い出してください。
private staticなmContextは、これを保持するActivityのライフサイクルが終了したとして
も、mContextによるActivityへの参照は破棄されず、メモリリークが発生します。
Contextへの参照を使用する場合に留意するべき点は下記となります。
- Contextの参照は関連するContextのライフサイクルに合わせる
(ApplicationContextならApplicationライフサイクルに、ActivityContextであれば
Activityのライフサイクルに合わせること)- 可能であればApplicationContextの使用を考える
- Activity内部に非staticなインナークラスの作成は極力避ける。
- 可能であればActivityへの参照は弱参照を用いる
Context参照がリークした場合、Activityとそれに紐付くインスタンス(特にViewやBitmap等)
が諸々リークするため、予想以上に大量のメモリリークとなる恐れがあります。
場合により、ガベージコレクタによるインスタンス回収が間に合わずOutOfMemory例外が
発生することもあります。(ガベージコレクタはメモリリーク保証しない)
Contextにまつわるメモリリーク問題のより詳細な情報は下記が参考になります。
http://developer.android.com/resources/articles/avoiding-memory-leaks.html
ActivityContextではメモリリークの可能性に考慮する必要があるのですね。