適当に使いがちなContext
fragmentのライフサイクルの勉強しているときに以下の記述を見つけました。
参照記事
https://qiita.com/K4N4/items/76d7bd8036ed98a0c271
フラグメントのライフサイクルにおいて、最初のメソッド。フラグメントとアクティビティ(コンテクスト)が関連付けられた時に呼ばれる。引数はアクティビティではなく、コンテクスト。他のメソッドにも共通する事であるが、フラグメントは基本的にアクティビティを参照するのではなく、コンテクストを参照する。
あーはいはいcontextね〜っていつもの如く読み流しながら思いました。
あれ?contextってなんだっけ?
結構なんとなくで誤魔化している人も多いんじゃないでしょうか(そんなことなかったらごめんなさい)
Android開発している時に様々な場面でContextと記述したり引数に渡すもののいまいち詳しく知る機会ってない気がします。
Contextとはそもそも何か
公式の説明(https://developer.android.com/reference/android/content/Context)
<雑翻訳>
アプリケーション環境に関するグローバル情報へのインターフェース。
Androidシステムによって実装が提供されている抽象クラス。
上記によりアプリケーション固有のリソースとクラスへのアクセス、およびアクティビティの起動、インテントのブロードキャストと受信などのアプリケーションレベルの操作のアップコールが可能になる。
つまりアプリ開発時に様々な環境や設定へアクセスするためのインターフェースなんですね。
Contextは抽象クラスで定義されている。
→ActivityもApplicationもContextクラスを継承している!!
この辺であー、だからthisでContextを引数に渡せるんだなあって改めて思いました。
Activityでstrings.xmlから文字列取得するときにgetStringできるのもContextを継承しているおかげだったんですね。
使う時になんか種類分かれてない?
Contextを取得する際に
getApplicationContext()
getContext()
とあり何が違うんだ?って思いながら使ってました(本当に良くない)
*一旦ここを読むことをお勧めします。
とってもわかりやすいです。
http://yuki312.blogspot.com/2012/02/thisgetapplicationcontextactivityapplic.html
ActivityContext
Activityのライフサイクルに従っている。
Acticityの終了後にContextへの参照が残っていると、メモリリークが...(後述の問題に関与)
→ ActivityContextを使う際にそのスコープ外で使ってはいけない。
→ライフサイクルを意識して実装しましょう。
ApplicationContext
Applicationのライフサイクルに従っている。
Viewに渡す際などApplicationのContextを渡しがちですがそもそもactivityのテーマと異なると想定と違うViewが作成されたり予期せぬ動作をするようです。
世の中には一旦困ったらApplicationContextを使っとけ!みたいなのもありますがちゃんとライフサイクルやスコープを確認して吟味するべきですね...予期せぬ動きも起こり得ますし反省。
ContextをViewModelで渡したらいけないのはなぜ
ViewModelでResourceから文字列を取得したい時にContextを渡していましたが良くないと教えられました。
なんでダメなんだろうなってなんとなく思っていましたがここまで来るとなんとなくわかりますね。
ActivityContextはactivityのライフサイクルに従っている!
→ViewModelの中でcontext持ってくるとactivityのライフサイクルが終わった時にメモリリークしちゃうからですね。
いやでもContextは欲しいんだけどって時はApplicationContextを付与していいんですかね?上記の観点から不具合も起きそうです。
大人しくBindingしたり外部クラス作成するべきなんですかね(詳しい方いたら教えてください)
おわりと補足
ライフサイクルの理解を深めようとContextを学んだら今度はライフサイクルの理解をもっと深める必要が起きてめちゃくちゃ密接なんだなと感じました。
基礎的な部分なのにそこそこ蔑ろにしていても実装面で困るシーンが少ないことは結構恐ろしいですね。
それだけ便利ってことでもあるのですが。
参照
https://qiita.com/K4N4/items/76d7bd8036ed98a0c271
https://www.torutk.com/projects/swe/wiki/Android%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-ViewModel
https://qiita.com/tkmd35/items/e6abeed6ac68cbac09ed
https://zenn.dev/issyu_39/articles/5225144dae22efc162fd