前回の日記で「ContextはApplicationを渡すのが基本(ドヤァ」なんてことを書いたが、それはちょっと言い過ぎで、やはり状況に応じたContextインスタンスを持つべきではある。
つまり、Applicationじゃ困ることもあるということだ。
例えば、三大Contextインスタンス(Activity、Service、Application…の3つと言えるだろう)の中でDialogを起動できるのはActivityだけである。DialogはWindowManagerやらを呼ぶためにコンストラクタでContextを要求する仕様になっているが、そこにServiceインスタンスを代入しても例外吐いて落ちるし、Applicationでもダメである。
正直この仕様は納得がいかない。Dialogを起動出来るのがActivityならば最初から引数型をActivityクラスにするべきではないのか? まぁ、Dialogで利用するのはContextのメソッドであってActivity特有のメソッドは使わない、というなら確かにContextでいいのかもしれないが、だとすればなぜ他のContextで落ちるのか(Contextを要求してるのにContextを継承したクラスのオブジェクトを渡して落ちるとか、コンパイラさんの立場が無いのではないか。型安全はどこへいった。)。ちょっとよく調べてないのでわからないが、たとえActivityの派生型以外から起動出来る仕組みにしているのだとしても、DialogOwnerInterfaceでも定義して、そいつを実装したクラスのインスタンスを渡させるべきではないのか。
まぁ私はプログラムの勉強を初めて日も浅いので、なにか見落としてる都合があるのかもしれないが…、実際紛らわしい仕様であることは確かだ。
また他にも、こちらのサイトで挙げられているようにBroadcastReceiverなどをregistするときにApplicationを渡してしまうとメモリリークの原因になってしまう、ということもある。
http://d.hatena.ne.jp/IchiRoku/20101230/1293717201
Contextは「そのContext自身の生存範囲と利用側の都合が一致しているかどうか」を常に意識して扱わなければならない、ということだろう。アプリケーション全体で静的に持ちたい情報(複数画面で共有される情報など)はApplicationContextで。アクティビティと運命を共にすべき(完全にアクティビティ子飼いのビューなど)ならばActivityContextで。
しかしそれを実践しようにもContextという抽象的な型でやりとりするのは紛らわしく思うのだが。
public class Hoge { Application mApp; Activity mActivity; public Hoge(Activity activity){ mActivity = activity; mApp = activity.getApplication(); } }
もういっそのこと、このような潔い持ち方をしたほうがいいんじゃなかろうか。
ちょっと納得がいかないことが多いので継続調査!